SSH/RDP credentials are now stored per user account, #3995
Ylian Saint-Hilaire committed
May 17, 2022 at 16:09 UTC
753b6c240a4050449267e6b10ca7d0692eb6e257
3 files changed
+141
-98
apprelays.js
+109
-83
@@ -215,28 +215,33 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) {
215
}
216
}
217
218
- // Save SSH credentials into device
218
+ // Save RDP credentials into database
219
function saveRdpCredentials() {
220
if (domain.allowsavingdevicecredentials == false) return;
221
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
222
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
223
const node = nodes[0];
224
- const changed = (node.rdp == null);
224
+ if (node.rdp == null) { node.rdp = {}; }
225
226
- // Check if credentials are the same
227
- if ((typeof node.rdp == 'object') && (node.rdp.d == obj.infos.domain) && (node.rdp.u == obj.infos.username) && (node.rdp.p == obj.infos.password)) return;
226
+ // Check if credentials are already set
227
+ if ((typeof node.rdp[obj.userid] == 'object') && (node.rdp[obj.userid].d == obj.infos.domain) && (node.rdp[obj.userid].u == obj.infos.username) && (node.rdp[obj.userid].p == obj.infos.password)) return;
228
+
229
+ // Clear up any existing credentials or credentials for users that don't exist anymore
230
+ for (var i in node.rdp) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.rdp[i]; } }
231
+
232
+ // Clear legacy credentials
233
+ delete node.rdp.d;
234
+ delete node.rdp.u;
235
+ delete node.rdp.p;
236
237
// Save the credentials
230
- node.rdp = { d: obj.infos.domain, u: obj.infos.username, p: obj.infos.password };
238
+ node.rdp[obj.userid] = { d: obj.infos.domain, u: obj.infos.username, p: obj.infos.password };
239
parent.parent.db.Set(node);
240
233
- // Event node change if needed
234
- if (changed) {
235
- // Event the node change
236
- const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: obj.userid, node: parent.CloneSafeNode(node), msg: "Changed RDP credentials" };
237
- if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
238
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
239
- }
241
+ // Event the node change
242
+ const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: obj.userid, node: parent.CloneSafeNode(node), msg: "Changed RDP credentials" };
243
+ if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
244
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
245
});
246
}
247
@@ -299,10 +304,10 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) {
304
// Check if we need to load server stored credentials
305
if ((typeof obj.infos.options == 'object') && (obj.infos.options.useServerCreds == true)) {
306
// Check if RDP credentials exist
302
- if ((domain.allowsavingdevicecredentials !== false) && (typeof node.rdp == 'object') && (typeof node.rdp.d == 'string') && (typeof node.rdp.u == 'string') && (typeof node.rdp.p == 'string')) {
303
- obj.infos.domain = node.rdp.d;
304
- obj.infos.username = node.rdp.u;
305
- obj.infos.password = node.rdp.p;
307
+ if ((domain.allowsavingdevicecredentials !== false) && (typeof node.rdp == 'object') && (typeof node.rdp[obj.userid] == 'object') && (typeof node.rdp[obj.userid].d == 'string') && (typeof node.rdp[obj.userid].u == 'string') && (typeof node.rdp[obj.userid].p == 'string')) {
308
+ obj.infos.domain = node.rdp[obj.userid].d;
309
+ obj.infos.username = node.rdp[obj.userid].u;
310
+ obj.infos.password = node.rdp[obj.userid].p;
311
startTcpServer();
312
} else {
313
// No server credentials.
@@ -382,7 +387,7 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) {
387
module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
388
const Net = require('net');
389
const WebSocket = require('ws');
385
-
390
+
391
// SerialTunnel object is used to embed SSH within another connection.
392
function SerialTunnel(options) {
393
const obj = new require('stream').Duplex(options);
@@ -447,36 +452,43 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
452
delete obj.cookie;
453
delete obj.nodeid;
454
delete obj.meshid;
455
+ delete obj.userid;
456
delete obj.ws;
457
};
458
453
- // Save SSH credentials into device
459
+ // Save SSH credentials into database
460
function saveSshCredentials(keep) {
461
if (((keep != 1) && (keep != 2)) || (domain.allowsavingdevicecredentials == false)) return;
462
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
463
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
464
const node = nodes[0];
459
- const changed = (node.ssh == null);
465
+ if (node.ssh == null) { node.ssh = {}; }
466
467
// Check if credentials are the same
462
- //if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
468
+ //if ((typeof node.ssh[obj.userid] == 'object') && (node.ssh[obj.userid].u == obj.username) && (node.ssh[obj.userid].p == obj.password)) return; // TODO
469
+
470
+ // Clear up any existing credentials or credentials for users that don't exist anymore
471
+ for (var i in node.ssh) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.ssh[i]; } }
472
+
473
+ // Clear legacy credentials
474
+ delete node.ssh.u;
475
+ delete node.ssh.p;
476
+ delete node.ssh.k;
477
+ delete node.ssh.kp;
478
479
// Save the credentials
480
if (obj.password != null) {
466
- node.ssh = { u: obj.username, p: obj.password };
481
+ node.ssh[obj.userid] = { u: obj.username, p: obj.password };
482
} else if (obj.privateKey != null) {
468
- node.ssh = { u: obj.username, k: obj.privateKey };
469
- if (keep == 2) { node.ssh.kp = obj.privateKeyPass; }
483
+ node.ssh[obj.userid] = { u: obj.username, k: obj.privateKey };
484
+ if (keep == 2) { node.ssh[obj.userid].kp = obj.privateKeyPass; }
485
} else return;
486
parent.parent.db.Set(node);
487
473
- // Event node change if needed
474
- if (changed) {
475
- // Event the node change
476
- const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: obj.userid, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
477
- if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
478
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
479
- }
488
+ // Event the node change
489
+ const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: obj.userid, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
490
+ if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
491
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
492
});
493
}
494
@@ -592,24 +604,24 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
604
parent.parent.db.Get(obj.cookie.nodeid, function (err, nodes) {
605
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
606
const node = nodes[0];
595
- if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || ((typeof node.ssh.p != 'string') && (typeof node.ssh.k != 'string'))) {
607
+ if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (node.ssh[user._id] == null) || (typeof node.ssh[user._id].u != 'string') || ((typeof node.ssh[user._id].p != 'string') && (typeof node.ssh[user._id].k != 'string'))) {
608
// Send a request for SSH authentication
609
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
598
- } else if ((domain.allowsavingdevicecredentials !== false) && (node.ssh != null) && (typeof node.ssh.k == 'string') && (node.ssh.kp == null)) {
610
+ } else if ((domain.allowsavingdevicecredentials !== false) && (node.ssh != null) && (typeof node.ssh[user._id].k == 'string') && (node.ssh[user._id].kp == null)) {
611
// Send a request for SSH authentication with option for only the private key password
600
- obj.username = node.ssh.u;
601
- obj.privateKey = node.ssh.k;
612
+ obj.username = node.ssh[user._id].u;
613
+ obj.privateKey = node.ssh[user._id].k;
614
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
615
} else {
616
// Use our existing credentials
617
obj.termSize = msg;
618
delete obj.keep;
607
- obj.username = node.ssh.u;
608
- if (typeof node.ssh.p == 'string') {
609
- obj.password = node.ssh.p;
610
- } else if (typeof node.ssh.k == 'string') {
611
- obj.privateKey = node.ssh.k;
612
- obj.privateKeyPass = node.ssh.kp;
619
+ obj.username = node.ssh[user._id].u;
620
+ if (typeof node.ssh[user._id].p == 'string') {
621
+ obj.password = node.ssh[user._id].p;
622
+ } else if (typeof node.ssh[user._id].k == 'string') {
623
+ obj.privateKey = node.ssh[user._id].k;
624
+ obj.privateKeyPass = node.ssh[user._id].kp;
625
}
626
startRelayConnection();
627
}
@@ -786,30 +798,37 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
798
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
799
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
800
const node = nodes[0];
789
- const changed = (node.ssh == null);
801
+ if (node.ssh == null) { node.ssh = {}; }
802
803
// Check if credentials are the same
804
//if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
805
806
+ // Clear up any existing credentials or credentials for users that don't exist anymore
807
+ for (var i in node.ssh) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.ssh[i]; } }
808
+
809
+ // Clear legacy credentials
810
+ delete node.ssh.u;
811
+ delete node.ssh.p;
812
+ delete node.ssh.k;
813
+ delete node.ssh.kp;
814
+
815
// Save the credentials
816
if (obj.password != null) {
796
- node.ssh = { u: obj.username, p: obj.password };
817
+ node.ssh[user._id] = { u: obj.username, p: obj.password };
818
} else if (obj.privateKey != null) {
798
- node.ssh = { u: obj.username, k: obj.privateKey };
799
- if (keep == 2) { node.ssh.kp = obj.privateKeyPass; }
819
+ node.ssh[user._id] = { u: obj.username, k: obj.privateKey };
820
+ if (keep == 2) { node.ssh[user._id].kp = obj.privateKeyPass; }
821
} else return;
822
parent.parent.db.Set(node);
823
803
- // Event node change if needed
804
- if (changed) {
805
- // Event the node change
806
- const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: user._id, username: user.name, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
807
- if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
808
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
809
- }
824
+ // Event the node change
825
+ const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: user._id, username: user.name, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
826
+ if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
827
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
828
});
829
}
830
831
+
832
// Start the looppback server
833
function startRelayConnection(authCookie) {
834
try {
@@ -1032,22 +1051,22 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
1051
ws._socket.resume();
1052
1053
// Check if we have SSH credentials for this device
1035
- if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || ((typeof node.ssh.p != 'string') && (typeof node.ssh.k != 'string'))) {
1054
+ if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (node.ssh[user._id] == null) || (typeof node.ssh[user._id].u != 'string') || ((typeof node.ssh[user._id].p != 'string') && (typeof node.ssh[user._id].k != 'string'))) {
1055
// Send a request for SSH authentication
1056
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
1038
- } else if ((typeof node.ssh.k == 'string') && (typeof node.ssh.kp != 'string')) {
1057
+ } else if ((typeof node.ssh[user._id].k == 'string') && (typeof node.ssh[user._id].kp != 'string')) {
1058
// Send a request for SSH authentication with option for only the private key password
1040
- obj.username = node.ssh.u;
1041
- obj.privateKey = node.ssh.k;
1059
+ obj.username = node.ssh[user._id].u;
1060
+ obj.privateKey = node.ssh[user._id].k;
1061
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
1062
} else {
1063
// Use our existing credentials
1045
- obj.username = node.ssh.u;
1046
- if (typeof node.ssh.p == 'string') {
1047
- obj.password = node.ssh.p;
1048
- } else if (typeof node.ssh.k == 'string') {
1049
- obj.privateKey = node.ssh.k;
1050
- obj.privateKeyPass = node.ssh.kp;
1064
+ obj.username = node.ssh[user._id].u;
1065
+ if (typeof node.ssh[user._id].p == 'string') {
1066
+ obj.password = node.ssh[user._id].p;
1067
+ } else if (typeof node.ssh[user._id].k == 'string') {
1068
+ obj.privateKey = node.ssh[user._id].k;
1069
+ obj.privateKeyPass = node.ssh[user._id].kp;
1070
}
1071
try { ws.send(JSON.stringify({ action: 'sshautoauth' })) } catch (ex) { }
1072
}
@@ -1132,30 +1151,37 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
1151
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
1152
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
1153
const node = nodes[0];
1135
- const changed = (node.ssh == null);
1154
+ if (node.rdp == null) { node.rdp = {}; }
1155
1156
// Check if credentials are the same
1138
- //if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
1157
+ //if ((typeof node.ssh[obj.userid] == 'object') && (node.ssh[obj.userid].u == obj.username) && (node.ssh[obj.userid].p == obj.password)) return; // TODO
1158
+
1159
+ // Clear up any existing credentials or credentials for users that don't exist anymore
1160
+ for (var i in node.ssh) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.ssh[i]; } }
1161
+
1162
+ // Clear legacy credentials
1163
+ delete node.ssh.u;
1164
+ delete node.ssh.p;
1165
+ delete node.ssh.k;
1166
+ delete node.ssh.kp;
1167
1168
// Save the credentials
1169
if (obj.password != null) {
1142
- node.ssh = { u: obj.username, p: obj.password };
1170
+ node.ssh[user._id] = { u: obj.username, p: obj.password };
1171
} else if (obj.privateKey != null) {
1144
- node.ssh = { u: obj.username, k: obj.privateKey };
1145
- if (keep == 2) { node.ssh.kp = obj.privateKeyPass; }
1172
+ node.ssh[user._id] = { u: obj.username, k: obj.privateKey };
1173
+ if (keep == 2) { node.ssh[user._id].kp = obj.privateKeyPass; }
1174
} else return;
1175
parent.parent.db.Set(node);
1176
1149
- // Event node change if needed
1150
- if (changed) {
1151
- // Event the node change
1152
- const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: user._id, username: user.name, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
1153
- if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
1154
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
1155
- }
1177
+ // Event the node change
1178
+ const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: user._id, username: user.name, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
1179
+ if (parent.parent.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
1180
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
1181
});
1182
}
1183
1184
+
1185
// Start the looppback server
1186
function startRelayConnection(authCookie) {
1187
try {
@@ -1554,22 +1580,22 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
1580
ws._socket.resume();
1581
1582
// Check if we have SSH credentials for this device
1557
- if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || ((typeof node.ssh.p != 'string') && (typeof node.ssh.k != 'string'))) {
1583
+ if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (node.ssh[user._id] == null) || (typeof node.ssh[user._id].u != 'string') || ((typeof node.ssh[user._id].p != 'string') && (typeof node.ssh[user._id].k != 'string'))) {
1584
// Send a request for SSH authentication
1585
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
1560
- } else if ((typeof node.ssh.k == 'string') && (typeof node.ssh.kp != 'string')) {
1586
+ } else if ((typeof node.ssh[user._id].k == 'string') && (typeof node.ssh[user._id].kp != 'string')) {
1587
// Send a request for SSH authentication with option for only the private key password
1562
- obj.username = node.ssh.u;
1563
- obj.privateKey = node.ssh.k;
1588
+ obj.username = node.ssh[user._id].u;
1589
+ obj.privateKey = node.ssh[user._id].k;
1590
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
1591
} else {
1592
// Use our existing credentials
1567
- obj.username = node.ssh.u;
1568
- if (typeof node.ssh.p == 'string') {
1569
- obj.password = node.ssh.p;
1570
- } else if (typeof node.ssh.k == 'string') {
1571
- obj.privateKey = node.ssh.k;
1572
- obj.privateKeyPass = node.ssh.kp;
1593
+ obj.username = node.ssh[user._id].u;
1594
+ if (typeof node.ssh[user._id].p == 'string') {
1595
+ obj.password = node.ssh[user._id].p;
1596
+ } else if (typeof node.ssh[user._id].k == 'string') {
1597
+ obj.privateKey = node.ssh[user._id].k;
1598
+ obj.privateKeyPass = node.ssh[user._id].kp;
1599
}
1600
1601
// Create a mesh relay authentication cookie
meshuser.js
+21
-10
@@ -423,9 +423,16 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
423
else if (event == 'updatefiles') { updateUserFiles(user, ws, domain); }
424
else {
425
// If updating guest device shares, if we are updating a user that is not creator of the share, remove the URL.
426
- if ((event.action == 'deviceShareUpdate') && (Array.isArray(event.deviceShares))) {
426
+ if (((event.action == 'deviceShareUpdate') && (Array.isArray(event.deviceShares))) || ((event.action == 'changenode') && (event.node != null) && ((event.node.rdp != null) || (event.node.ssh != null)))) {
427
event = common.Clone(event);
428
- for (var i in event.deviceShares) { if (event.deviceShares[i].userid != user._id) { delete event.deviceShares[i].url; } }
428
+ if ((event.action == 'deviceShareUpdate') && (Array.isArray(event.deviceShares))) {
429
+ for (var i in event.deviceShares) { if (event.deviceShares[i].userid != user._id) { delete event.deviceShares[i].url; } }
430
+ }
431
+ if ((event.action == 'changenode') && (event.node != null) && ((event.node.rdp != null) || (event.node.ssh != null))) {
432
+ // Clean up RDP & SSH credentials
433
+ if ((event.node.rdp != null) && (typeof event.node.rdp[user._id] == 'number')) { event.node.rdp = event.node.rdp[user._id]; } else { delete event.node.rdp; }
434
+ if ((event.node.ssh != null) && (typeof event.node.ssh[user._id] == 'number')) { event.node.ssh = event.node.ssh[user._id]; } else { delete event.node.ssh; }
435
+ }
436
}
437
438
// This is a MeshCentral Satellite message
@@ -730,18 +737,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
737
738
// Remove SSH credentials if present
739
if (docs[i].ssh != null) {
733
- if (docs[i].ssh.u) {
734
- if (docs[i].ssh.k && docs[i].ssh.kp) { docs[i].ssh = 2; } // Username, key and password
735
- else if (docs[i].ssh.k) { docs[i].ssh = 3; } // Username and key. No password.
736
- else if (docs[i].ssh.p) { docs[i].ssh = 1; } // Username and password
740
+ if ((docs[i].ssh[obj.user._id] != null) && (docs[i].ssh[obj.user._id].u)) {
741
+ if (docs[i].ssh.k && docs[i].ssh[obj.user._id].kp) { docs[i].ssh = 2; } // Username, key and password
742
+ else if (docs[i].ssh[obj.user._id].k) { docs[i].ssh = 3; } // Username and key. No password.
743
+ else if (docs[i].ssh[obj.user._id].p) { docs[i].ssh = 1; } // Username and password
744
else { delete docs[i].ssh; }
745
} else {
746
delete docs[i].ssh;
747
}
748
}
749
743
- // Remove RDP credentials if present
744
- if (docs[i].rdp != null) { docs[i].rdp = 1; }
750
+ // Remove RDP credentials if present, only set to 1 if our userid has RDP credentials
751
+ if ((docs[i].rdp != null) && (docs[i].rdp[obj.user._id] != null)) { docs[i].rdp = 1; } else { delete docs[i].rdp; }
752
753
// Remove Intel AMT credential if present
754
if (docs[i].intelamt != null) {
@@ -3014,13 +3021,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3021
}
3022
3023
if ((typeof command.ssh == 'number') && (command.ssh == 0)) {
3017
- if (node.ssh != null) { delete node.ssh; change = 1; changes.push('ssh'); } // Delete the SSH cendentials
3024
+ if ((node.ssh != null) && (node.ssh[user._id] != null)) { delete node.ssh[user._id]; change = 1; changes.push('ssh'); } // Delete the SSH cendentials
3025
}
3026
3027
if ((typeof command.rdp == 'number') && (command.rdp == 0)) {
3021
- if (node.rdp != null) { delete node.rdp; change = 1; changes.push('rdp'); } // Delete the RDP cendentials
3028
+ if ((node.rdp != null) && (node.rdp[user._id] != null)) { delete node.rdp[user._id]; change = 1; changes.push('rdp'); } // Delete the RDP cendentials
3029
}
3030
3031
+ // Clean up any legacy RDP and SSH credentials
3032
+ if (node.rdp != null) { delete node.rdp.d; delete node.rdp.u; delete node.rdp.p; }
3033
+ if (node.ssh != null) { delete node.ssh.u; delete node.ssh.p; delete node.ssh.k; delete node.ssh.kp; }
3034
+
3035
if (domain.geolocation && command.userloc && ((node.userloc == null) || (command.userloc[0] != node.userloc[0]) || (command.userloc[1] != node.userloc[1]))) {
3036
change = 1;
3037
if ((command.userloc.length == 0) && (node.userloc)) {
webserver.js
+11
-5
@@ -7533,12 +7533,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
7533
if ((r.pmt != null) || (r.ssh != null) || (r.rdp != null) || ((r.intelamt != null) && ((r.intelamt.pass != null) || (r.intelamt.mpspass != null)))) {
7534
r = Object.assign({}, r); // Shallow clone
7535
if (r.pmt != null) { r.pmt = 1; }
7536
- if (r.ssh && r.ssh.u) {
7537
- if (r.ssh.p) { r.ssh = 1; } // Username and password
7538
- else if (r.ssh.k && r.ssh.kp) { r.ssh = 2; } // Username, key and password
7539
- else if (r.ssh.k) { r.ssh = 3; } // Username and key. No password.
7536
+ if (r.ssh != null) {
7537
+ var n = {};
7538
+ for (var i in r.ssh) {
7539
+ if (i.startsWith('user/')) {
7540
+ if (r.ssh[i].p) { n[i] = 1; } // Username and password
7541
+ else if (r.ssh[i].k && r.ssh[i].kp) { n[i] = 2; } // Username, key and password
7542
+ else if (r.ssh[i].k) { n[i] = 3; } // Username and key. No password.
7543
+ }
7544
+ }
7545
+ r.ssh = n;
7546
}
7541
- if (r.rdp != null) { r.rdp = 1; }
7547
+ if (r.rdp != null) { var n = {}; for (var i in r.rdp) { if (i.startsWith('user/')) { n[i] = 1; } } r.rdp = n; }
7548
if ((r.intelamt != null) && ((r.intelamt.pass != null) || (r.intelamt.mpspass != null))) {
7549
r.intelamt = Object.assign({}, r.intelamt); // Shallow clone
7550
if (r.intelamt.pass != null) { r.intelamt.pass = 1; }; // Remove the Intel AMT administrator password from the node