Added user authentication option.

Ylian Saint-Hilaire committed Oct 11, 2018 at 13:29 UTC 207bad322aa186955b748e29949a79d40f9f6936
13 files changed +172 -117
agents/MeshCmd-signed.exe
Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ
agents/MeshCmd64-signed.exe
Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ
agents/MeshService-signed.exe
Binary files a/agents/MeshService-signed.exe and b/agents/MeshService-signed.exe differ
agents/MeshService.exe
Binary files a/agents/MeshService.exe and b/agents/MeshService.exe differ
agents/MeshService64-signed.exe
Binary files a/agents/MeshService64-signed.exe and b/agents/MeshService64-signed.exe differ
agents/MeshService64.exe
Binary files a/agents/MeshService64.exe and b/agents/MeshService64.exe differ
agents/meshcmd.js
+22 -18
@@ -342,9 +342,9 @@ function run(argv) {
342 var amtMeiModule = require('amt-mei');
343 var amtMei = new amtMeiModule();
344 amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
345 - amtMei.getVersion(function (val) { for (var version in val.Versions) { if (val.Versions[version].Description == 'AMT') { mestate.ver = val.Versions[version].Version; } } });
346 - amtMei.getProvisioningState(function (result) { mestate.ProvisioningState = result; });
347 - amtMei.getProvisioningMode(function (result) { mestate.ProvisioningMode = result; });
345 + amtMei.getVersion(function (result) { if (result) { for (var version in result.Versions) { if (result.Versions[version].Description == 'AMT') { mestate.ver = result.Versions[version].Version; } } } });
346 + amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } });
347 + amtMei.getProvisioningMode(function (result) { if (result) { mestate.ProvisioningMode = result; } });
348 amtMei.getEHBCState(function (result) { if (result) { mestate.ehbc = result; } });
349 amtMei.getControlMode(function (result) { if (result) { mestate.controlmode = result; } });
350 amtMei.getMACAddresses(function (result) { if (result) { mestate.mac = result; } });
@@ -352,24 +352,28 @@ function run(argv) {
352 amtMei.getLanInterfaceSettings(1, function (result) { if (result) { mestate.net1 = result; } });
353 amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } });
354 amtMei.getDnsSuffix(function (result) {
355 - mestate.dns = result;
356 - var str = 'Intel AMT v' + mestate.ver;
357 - if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; }
358 - else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; }
359 - else if (mestate.ProvisioningState.stateStr == 'POST') {
360 - if (mestate.ProvisioningMode) {
361 - if (mestate.controlmode) {
362 - if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; }
363 - } else {
364 - str += ', activated in ' + mestate.ProvisioningMode.modeStr;
355 + if (result) { mestate.dns = result; }
356 + if (mestate.ver && mestate.ProvisioningState && mestate.ProvisioningMode) {
357 + var str = 'Intel AMT v' + mestate.ver;
358 + if (mestate.ProvisioningState.stateStr == 'PRE') { str += ', pre-provisioning state'; }
359 + else if (mestate.ProvisioningState.stateStr == 'IN') { str += ', in-provisioning state'; }
360 + else if (mestate.ProvisioningState.stateStr == 'POST') {
361 + if (mestate.ProvisioningMode) {
362 + if (mestate.controlmode) {
363 + if (mestate.ProvisioningMode.modeStr == 'ENTERPRISE') { str += ', activated in ' + ["none", "client control mode", "admin control mode", "remote assistance mode"][mestate.controlmode.controlMode]; } else { str += ', activated in ' + mestate.ProvisioningMode.modeStr; }
364 + } else {
365 + str += ', activated in ' + mestate.ProvisioningMode.modeStr;
366 + }
367 }
368 }
369 + if ((mestate.ehbc) && (mestate.ehbc.EHBC == true)) { str += ', EHBC enabled'; }
370 + str += '.';
371 + 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)); }
372 + 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)); }
373 + console.log(str + '.');
374 + } else {
375 + console.log('Intel(R) AMT not supported.');
376 }
368 - if ((mestate.ehbc) && (mestate.ehbc.EHBC == true)) { str += ', EHBC enabled'; }
369 - str += '.';
370 - 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)); }
371 - 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)); }
372 - console.log(str + '.');
377 exit(1);
378 });
379 } else if (settings.action == 'amtinfodebug') {
agents/modules_meshcore/linux-dbus.js
+1 -1
@@ -25,7 +25,7 @@ function dbus(address, uid)
25 .createEvent('signal');
26 Object.defineProperty(this, "uid", { value: uid });
27 this._child = require('child_process').execFile("/bin/sh", ["sh"], { type: require('child_process').SpawnTypes.TERM, uid: uid == null ? -1 : uid });
28 - this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while true; do read X; echo "$X"; done )\n');
28 + this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while read X; do echo "$X"; done )\n');
29 this._child.stdout.dbus = this;
30 this._child.stdout.on('data', function (chunk)
31 {
meshuser.js
+11 -8
@@ -86,7 +86,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
86 req.session.currentNode = '';
87 } else {
88 // Close the websocket connection
89 - try { obj.ws.close(); } catch (e) { } return;
89 + console.log('NOAUTH1');
90 + ws.send(JSON.stringify({ action: 'close', cause: 'noauth' }));
91 + try { obj.ws.close(); } catch (e) { }
92 + return;
93 }
94 }
95 req.session.ws = obj.ws; // Associate this websocket session with the web session
@@ -120,8 +123,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
123 }
124 };
125
123 - user.subscriptions = obj.parent.subscribe(user._id, ws); // Subscribe to events
124 - obj.ws._socket.setKeepAlive(true, 240000); // Set TCP keep alive
126 + user.subscriptions = obj.parent.subscribe(user._id, ws); // Subscribe to events
127 + try { obj.ws._socket.setKeepAlive(true, 240000); } catch (ex) { } // Set TCP keep alive
128
129 // Send current server statistics
130 obj.SendServerStats = function () {
@@ -329,7 +332,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
332 command.sessionid = ws.sessionId; // Set the session id, required for responses.
333 command.rights = rights.rights; // Add user rights flags to the message
334 delete command.nodeid; // Remove the nodeid since it's implyed.
332 - agent.send(JSON.stringify(command));
335 + try { agent.send(JSON.stringify(command)); } catch (ex) { }
336 }
337 } else {
338 // Check if a peer server is connected to this agent
@@ -601,7 +604,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
604
605 // Get the list of sessions for this user
606 var sessions = obj.parent.wssessions[command.userid];
604 - if (sessions != null) { for (i in sessions) { sessions[i].send(JSON.stringify(notification)); } }
607 + if (sessions != null) { for (i in sessions) { try { sessions[i].send(JSON.stringify(notification)); } catch (ex) { } } }
608
609 if (obj.parent.parent.multiServer != null) {
610 // TODO: Add multi-server support
@@ -925,7 +928,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
928 var agent = obj.parent.wsagents[i];
929 if ((targetMeshes.indexOf(agent.dbMeshKey) >= 0) && (agent.authenticated == 2)) {
930 //console.log('Asking agent ' + agent.dbNodeKey + ' to wake ' + macs.join(','));
928 - agent.send(JSON.stringify({ action: 'wakeonlan', macs: macs }));
931 + try { agent.send(JSON.stringify({ action: 'wakeonlan', macs: macs })); } catch (ex) { }
932 wakeActions++;
933 }
934 }
@@ -966,7 +969,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
969 var agent = obj.parent.wsagents[node._id];
970 if (agent != null) {
971 // Send the power command
969 - agent.send(JSON.stringify({ action: 'poweraction', actiontype: command.actiontype }));
972 + try { agent.send(JSON.stringify({ action: 'poweraction', actiontype: command.actiontype })); } catch (ex) { }
973 powerActions++;
974 }
975 }
@@ -1004,7 +1007,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
1007 var agent = obj.parent.wsagents[node._id];
1008 if (agent != null) {
1009 // Send the power command
1007 - agent.send(JSON.stringify({ action: 'toast', title: command.title, msg: command.msg }));
1010 + try { agent.send(JSON.stringify({ action: 'toast', title: command.title, msg: command.msg })); } catch (ex) { }
1011 }
1012 }
1013 }
mpsserver.js
+1 -1
@@ -679,7 +679,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
679 };
680
681 function ChangeHostname(socket, host) {
682 - if (socket.tag.host == host) return; // Nothing to change
682 + if (socket.tag.host === host) return; // Nothing to change
683 socket.tag.host = host;
684
685 // Change the device
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.2.2-c",
3 + "version": "0.2.2-d",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
views/default.handlebars
+84 -86
@@ -155,58 +155,59 @@
155 <div id=devViewButton3 class=viewSelector onclick=onDeviceViewChange(3) title="Desktops"><div class="viewSelector3"></div></div>
156 <div id=devViewButton4 class=viewSelector onclick=onDeviceViewChange(4) title="Map"><div class="viewSelector4"></div></div>
157 </div><div><h1>My Devices</h1></div>
158 - <div style=width:100%;height:24px;background-color:#d3d9d6>
159 - <div class=h1 style=height:100%;float:left>&nbsp;</div>
160 - <div id=devListToolbar class=style14 style="height:100%;float:left;vertical-align:middle">
161 - &nbsp;&nbsp;<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All" />&nbsp;
162 - <input type=button id=GroupActionButton disabled="disabled" value="Group Action" onclick=groupActionFunction() />&nbsp;
163 - <input id=SearchInput type=text style=width:120px placeholder=Search onchange=onSearchInputChanged() onkeyup=onSearchInputChanged() autocomplete=off onfocus=onSearchFocus(1) onblur=onSearchFocus(0) />&nbsp;
164 - <input type=checkbox id=RealNameCheckBox onclick=onRealNameCheckBox() /><span title="Show devices operating system name">OS Name</span>
165 - </div>
166 - <div id=kvmListToolbar class=style14 style=height:100%;float:left>
167 - &nbsp;&nbsp;<input type="button" onclick="connectAllKvmFunction()" value="Connect All" />&nbsp;
168 - <input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All" />&nbsp;
169 - <input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect" />Auto&nbsp;
170 - <input type="button" onclick="showMultiDesktopSettings()" value="Settings" />&nbsp;
171 - </div>
172 - <div id=devMapToolbar class=style14 style=height:100%;float:left>
173 - &nbsp;&nbsp;<input type=text id=mapSearchLocation placeholder="Search Location" onfocus=onMapSearchFocus(1) onblur=onMapSearchFocus(0) />
174 - <input type=button value=Search title="Search for location" onclick=getSearchLocation() />
175 - <input type=button id=refreshmap title="Reset map view" value=Reset style=margin-left:5px onclick=refreshMap(false,true) />
176 - </div>
177 - <div class="auto-style1" style=height:100%;float:right>
178 - <div style="height:100%;width:4px;float:right;background-color:#ffffff"></div>
179 - <div class=h2 style="height:100%;float:right">&nbsp;</div>
180 - <div style="float:right;display:none" id=devListToolbarView>
181 - View
182 - <select id=viewselect onchange=onDeviceViewChange()>
183 - <option value=1>Columns</option>
184 - <option value=2>List</option>
185 - <option value=3>Desktops</option>
186 - <option id=viewselectmapoption value=4>Map</option>
187 - </select>
188 - </div>
189 - <div style=float:right id=devListToolbarSort>
190 - Sort
191 - <select id=sortselect onchange=onSortSelectChange()>
192 - <option>Group</option>
193 - <option>Power</option>
194 - <option>Device</option>
195 - <option>Tags</option>
196 - </select>
197 - &nbsp;
198 - </div>
199 - <div style=float:right id=devListToolbarSize>
200 - Size
201 - <select id=sizeselect onchange=onDeviceViewChange()>
202 - <option value=0>Small</option>
203 - <option value=1>Medium</option>
204 - <option value=2>Large</option>
205 - </select>
206 - &nbsp;
207 - </div>
208 - </div>
209 - </div>
158 + <table style=width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0>
159 + <tr>
160 + <td class=h1></td>
161 + <td id=devListToolbar class=style14>
162 + &nbsp;&nbsp;<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All" />&nbsp;
163 + <input type=button id=GroupActionButton disabled="disabled" value="Group Action" onclick=groupActionFunction() />&nbsp;
164 + <input id=SearchInput type=text style=width:120px placeholder=Search onchange=onSearchInputChanged() onkeyup=onSearchInputChanged() autocomplete=off onfocus=onSearchFocus(1) onblur=onSearchFocus(0) />&nbsp;
165 + <input type=checkbox id=RealNameCheckBox onclick=onRealNameCheckBox() /><span title="Show devices operating system name">OS Name</span>
166 + </td>
167 + <td id=kvmListToolbar class=style14 style=height:100%>
168 + &nbsp;&nbsp;<input type="button" onclick="connectAllKvmFunction()" value="Connect All" />&nbsp;
169 + <input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All" />&nbsp;
170 + <input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect" />Auto&nbsp;
171 + <input type="button" onclick="showMultiDesktopSettings()" value="Settings" />&nbsp;
172 + </td>
173 + <td id=devMapToolbar class=style14 style=height:100%>
174 + &nbsp;&nbsp;<input type=text id=mapSearchLocation placeholder="Search Location" onfocus=onMapSearchFocus(1) onblur=onMapSearchFocus(0) />
175 + <input type=button value=Search title="Search for location" onclick=getSearchLocation() />
176 + <input type=button id=refreshmap title="Reset map view" value=Reset style=margin-left:5px onclick=refreshMap(false,true) />
177 + </td>
178 + <td class="auto-style1" style=height:100%>
179 + <div style="float:right;display:none" id=devListToolbarView>
180 + View
181 + <select id=viewselect onchange=onDeviceViewChange()>
182 + <option value=1>Columns</option>
183 + <option value=2>List</option>
184 + <option value=3>Desktops</option>
185 + <option id=viewselectmapoption value=4>Map</option>
186 + </select>
187 + </div>
188 + <div style=float:right id=devListToolbarSort>
189 + Sort
190 + <select id=sortselect onchange=onSortSelectChange()>
191 + <option>Group</option>
192 + <option>Power</option>
193 + <option>Device</option>
194 + <option>Tags</option>
195 + </select>
196 + &nbsp;
197 + </div>
198 + <div style=float:right id=devListToolbarSize>
199 + Size
200 + <select id=sizeselect onchange=onDeviceViewChange()>
201 + <option value=0>Small</option>
202 + <option value=1>Medium</option>
203 + <option value=2>Large</option>
204 + </select>
205 + &nbsp;
206 + </div>
207 + </td>
208 + <td class=h2></td>
209 + </tr>
210 + </table>
211 <div id=NoMeshesPanel style=display:none>
212 <table style="width:100%;padding:20px">
213 <tr>
@@ -253,40 +254,38 @@
254 </div>
255 <div id=p3 style=display:none>
256 <h1>My Events</h1>
256 - <div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
257 - <div class=style7 style=width:16px;height:100%;float:left>&nbsp;</div>
258 - <div class=h1 style=height:100%;float:left>&nbsp;</div>
259 - <div class=style14 style=height:100%;float:left>&nbsp;&nbsp;<input id=p2deleteall type=button onclick=showDeleteAllEventsDialog() style=display:none value="Delete All..." />&nbsp;</div>
260 - <div class="auto-style1" style="height:100%;float:right">
261 - Show
262 - <select id=p3limitdropdown onchange=refreshEvents()>
263 - <option value=60>Last 60</option>
264 - <option value=120>Last 120</option>
265 - <option value=250>Last 250</option>
266 - <option value=500>Last 500</option>
267 - <option value=1000>Last 1000</option>
268 - </select>
269 - <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div>
270 - <div class="h2" style="height:100%;float:right;">&nbsp;</div>
271 - </div>
272 - </div>
257 + <table style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0>
258 + <tr>
259 + <td class=h1></td>
260 + <td>&nbsp;<input id=p2deleteall type=button onclick=showDeleteAllEventsDialog() style=display:none value="Delete All..." /></td>
261 + <td class=auto-style1>
262 + Show
263 + <select id=p3limitdropdown onchange=refreshEvents()>
264 + <option value=60>Last 60</option>
265 + <option value=120>Last 120</option>
266 + <option value=250>Last 250</option>
267 + <option value=500>Last 500</option>
268 + <option value=1000>Last 1000</option>
269 + </select>
270 + </td>
271 + <td class=h2></td>
272 + </tr>
273 + </table>
274 <div id=p3events style="height:calc(100vh - 243px);overflow-y:scroll"></div>
275 </div>
276 <div id=p4 style=display:none>
277 <h1>My Users</h1>
277 - <div style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px>
278 - <div class=style7 style=width:16px;height:100%;float:left>&nbsp;</div>
279 - <div class=h1 style=height:100%;float:left>&nbsp;</div>
280 - <div class=style14 style=height:100%;float:left>
281 - &nbsp;&nbsp;
282 - <input type=button onclick=showCreateNewAccountDialog() value="New Account..." />&nbsp;
283 - <input id=UserSearchInput type=text style=width:120px placeholder=Search onchange=onUserSearchInputChanged() onkeyup=onUserSearchInputChanged() autocomplete=off onfocus=onUserSearchFocus(1) onblur=onUserSearchFocus(0) />&nbsp;
284 - </div>
285 - <div class=auto-style1 style="height:100%;float:right">
286 - <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div>
287 - <div class=h2 style="height:100%;float:right">&nbsp;</div>
288 - </div>
289 - </div>
278 + <table style=width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0>
279 + <tr>
280 + <td class=h1></td>
281 + <td class=style14>
282 + &nbsp;
283 + <input type=button onclick=showCreateNewAccountDialog() value="New Account..." />&nbsp;
284 + <input id=UserSearchInput type=text style=width:120px placeholder=Search onchange=onUserSearchInputChanged() onkeyup=onUserSearchInputChanged() autocomplete=off onfocus=onUserSearchFocus(1) onblur=onUserSearchFocus(0) />&nbsp;
285 + </td>
286 + <td class=h2></td>
287 + </tr>
288 + </table>
289 <div id="p3users" style="max-height:calc(100vh - 243px);overflow-y:auto"></div>
290 </div>
291 <div id=p5 style=display:none>
@@ -1235,7 +1234,7 @@
1234 x += addHtmlValue2('Current Version', '<b>' + EscapeHtml(message.current) + '</b>');
1235 x += addHtmlValue2('Latest Version', '<b>' + EscapeHtml(message.latest) + '</b>');
1236 x += '</div>';
1238 - if ((message.current == message.latest) || ((features & 2048) == 0)) {
1237 + if ((message.latest.indexOf('.') == -1) || (message.current == message.latest) || ((features & 2048) == 0)) {
1238 setDialogMode(2, "MeshCentral Version", 1, null, x);
1239 } else {
1240 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 @@
2594 } catch (ex) {
2595 console.log(ex);
2596 QV('viewselectmapoption', false);
2597 + QV('devViewButton4', false);
2598 xxmap = null;
2599 }
2600 }
@@ -6176,9 +6176,7 @@
6176 for (var i in message.values) {
6177 x += '<div class=userTableHeader style=margin-bottom:4px;width:200px>' + i + '</div>';
6178 for (var j in message.values[i]) {
6179 - x += '<div style=width:300px;display:inline-block><div class=bar style=height:24px;width:100%;font-size:medium>';
6180 - x += '<div class=g1 style=height:24px;float:left></div><div class=g2 style=height:24px;float:right></div>';
6181 - x += '<div><span>' + j + '</span><span style=float:right>' + message.values[i][j] + '</span></div></div></div>';
6179 + 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>';
6180 }
6181 }
6182 }
webserver.js
+52 -2
@@ -214,7 +214,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
214 if (!module.parent) console.log('authenticating %s:%s:%s', domain.id, name, pass);
215 var user = obj.users['user/' + domain.id + '/' + name.toLowerCase()];
216 // Query the db for the given username
217 - if (!user) return fn(new Error('cannot find user'));
217 + if (!user) { fn(new Error('cannot find user')); return; }
218 // Apply the same algorithm to the POSTed password, applying the hash against the pass / salt, if there is a match we found the user
219 if (user.salt == null) {
220 fn(new Error('invalid password'));
@@ -1803,7 +1803,6 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1803 obj.app.post(url + 'amtevents.ashx', obj.handleAmtEventRequest);
1804 obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); });
1805 obj.app.ws(url + 'webrelay.ashx', handleRelayWebSocket);
1806 - 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); } });
1806 obj.app.get(url + 'meshagents', obj.handleMeshAgentRequest);
1807 obj.app.get(url + 'meshosxagent', obj.handleMeshOsxAgentRequest);
1808 obj.app.get(url + 'meshsettings', obj.handleMeshSettingsRequest);
@@ -1814,6 +1813,57 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1813 obj.app.ws(url + 'echo.ashx', handleEchoWebSocket);
1814 obj.app.ws(url + 'meshrelay.ashx', function (ws, req) { try { obj.meshRelayHandler.CreateMeshRelay(obj, ws, req, getDomain(req)); } catch (e) { console.log(e); } });
1815
1816 + // User login
1817 + obj.app.ws(url + 'control.ashx', function (ws, req) {
1818 + try {
1819 + var domain = checkUserIpAddress(ws, req);
1820 + if (domain != null) {
1821 + var loginok = false;
1822 + // Check if the user is logged in
1823 + if ((!req.session) || (!req.session.userid) || (req.session.domainid != domain.id)) {
1824 + // If a default user is active, setup the session here.
1825 + if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
1826 + if (req.session && req.session.loginmode) { delete req.session.loginmode; }
1827 + req.session.userid = 'user/' + domain.id + '/' + obj.args.user.toLowerCase();
1828 + req.session.domainid = domain.id;
1829 + req.session.currentNode = '';
1830 + obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
1831 + loginok = true;
1832 + } else {
1833 + // See the the user/pass is provided in URL arguments
1834 + if ((req.query.user != null) && (req.query.pass != null)) {
1835 + loginok = true;
1836 + obj.authenticate(req.query.user, req.query.pass, domain, function (err, userid) {
1837 + var loginok2 = false;
1838 + if (err == null) {
1839 + var user = obj.users[userid];
1840 + if (user) {
1841 + req.session.userid = userid;
1842 + req.session.domainid = domain.id;
1843 + req.session.currentNode = '';
1844 + obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
1845 + loginok2 = true;
1846 + }
1847 + }
1848 + if (loginok2 == false) {
1849 + // Close the websocket connection
1850 + try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { }
1851 + }
1852 + });
1853 + }
1854 + }
1855 + } else {
1856 + obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws, req, obj.args, domain); // Accept the connection
1857 + loginok = true;
1858 + }
1859 + if (loginok == false) {
1860 + // Close the websocket connection
1861 + try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth' })); ws.close(); } catch (e) { }
1862 + }
1863 + }
1864 + } catch (e) { console.log(e); }
1865 + });
1866 +
1867 // Server picture
1868 obj.app.get(url + 'serverpic.ashx', function (req, res) {
1869 // Check if we have "server.png" in the data folder, if so, use that.