This commit is contained in:
silversword411 2022-05-19 01:08:39 -04:00
commit 966e05497a
7 changed files with 183 additions and 122 deletions

View File

@ -215,28 +215,33 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) {
}
}
// Save SSH credentials into device
// Save RDP credentials into database
function saveRdpCredentials() {
if (domain.allowsavingdevicecredentials == false) return;
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
const changed = (node.rdp == null);
if (node.rdp == null) { node.rdp = {}; }
// Check if credentials are the same
if ((typeof node.rdp == 'object') && (node.rdp.d == obj.infos.domain) && (node.rdp.u == obj.infos.username) && (node.rdp.p == obj.infos.password)) return;
// Check if credentials are already set
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;
// Clear up any existing credentials or credentials for users that don't exist anymore
for (var i in node.rdp) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.rdp[i]; } }
// Clear legacy credentials
delete node.rdp.d;
delete node.rdp.u;
delete node.rdp.p;
// Save the credentials
node.rdp = { d: obj.infos.domain, u: obj.infos.username, p: obj.infos.password };
node.rdp[obj.userid] = { d: obj.infos.domain, u: obj.infos.username, p: obj.infos.password };
parent.parent.db.Set(node);
// Event node change if needed
if (changed) {
// Event the node change
const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: obj.userid, node: parent.CloneSafeNode(node), msg: "Changed RDP credentials" };
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.
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
}
});
}
@ -299,10 +304,10 @@ module.exports.CreateMstscRelay = function (parent, db, ws, req, args, domain) {
// Check if we need to load server stored credentials
if ((typeof obj.infos.options == 'object') && (obj.infos.options.useServerCreds == true)) {
// Check if RDP credentials exist
if ((domain.allowsavingdevicecredentials !== false) && (typeof node.rdp == 'object') && (typeof node.rdp.d == 'string') && (typeof node.rdp.u == 'string') && (typeof node.rdp.p == 'string')) {
obj.infos.domain = node.rdp.d;
obj.infos.username = node.rdp.u;
obj.infos.password = node.rdp.p;
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')) {
obj.infos.domain = node.rdp[obj.userid].d;
obj.infos.username = node.rdp[obj.userid].u;
obj.infos.password = node.rdp[obj.userid].p;
startTcpServer();
} else {
// No server credentials.
@ -447,36 +452,43 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
delete obj.cookie;
delete obj.nodeid;
delete obj.meshid;
delete obj.userid;
delete obj.ws;
};
// Save SSH credentials into device
// Save SSH credentials into database
function saveSshCredentials(keep) {
if (((keep != 1) && (keep != 2)) || (domain.allowsavingdevicecredentials == false)) return;
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
const changed = (node.ssh == null);
if (node.ssh == null) { node.ssh = {}; }
// Check if credentials are the same
//if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
//if ((typeof node.ssh[obj.userid] == 'object') && (node.ssh[obj.userid].u == obj.username) && (node.ssh[obj.userid].p == obj.password)) return; // TODO
// Clear up any existing credentials or credentials for users that don't exist anymore
for (var i in node.ssh) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.ssh[i]; } }
// Clear legacy credentials
delete node.ssh.u;
delete node.ssh.p;
delete node.ssh.k;
delete node.ssh.kp;
// Save the credentials
if (obj.password != null) {
node.ssh = { u: obj.username, p: obj.password };
node.ssh[obj.userid] = { u: obj.username, p: obj.password };
} else if (obj.privateKey != null) {
node.ssh = { u: obj.username, k: obj.privateKey };
if (keep == 2) { node.ssh.kp = obj.privateKeyPass; }
node.ssh[obj.userid] = { u: obj.username, k: obj.privateKey };
if (keep == 2) { node.ssh[obj.userid].kp = obj.privateKeyPass; }
} else return;
parent.parent.db.Set(node);
// Event node change if needed
if (changed) {
// Event the node change
const event = { etype: 'node', action: 'changenode', nodeid: obj.nodeid, domain: domain.id, userid: obj.userid, node: parent.CloneSafeNode(node), msg: "Changed SSH credentials" };
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.
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
}
});
}
@ -592,24 +604,24 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
parent.parent.db.Get(obj.cookie.nodeid, function (err, nodes) {
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
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'))) {
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'))) {
// Send a request for SSH authentication
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
} else if ((domain.allowsavingdevicecredentials !== false) && (node.ssh != null) && (typeof node.ssh.k == 'string') && (node.ssh.kp == null)) {
} else if ((domain.allowsavingdevicecredentials !== false) && (node.ssh != null) && (typeof node.ssh[user._id].k == 'string') && (node.ssh[user._id].kp == null)) {
// Send a request for SSH authentication with option for only the private key password
obj.username = node.ssh.u;
obj.privateKey = node.ssh.k;
obj.username = node.ssh[user._id].u;
obj.privateKey = node.ssh[user._id].k;
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
} else {
// Use our existing credentials
obj.termSize = msg;
delete obj.keep;
obj.username = node.ssh.u;
if (typeof node.ssh.p == 'string') {
obj.password = node.ssh.p;
} else if (typeof node.ssh.k == 'string') {
obj.privateKey = node.ssh.k;
obj.privateKeyPass = node.ssh.kp;
obj.username = node.ssh[user._id].u;
if (typeof node.ssh[user._id].p == 'string') {
obj.password = node.ssh[user._id].p;
} else if (typeof node.ssh[user._id].k == 'string') {
obj.privateKey = node.ssh[user._id].k;
obj.privateKeyPass = node.ssh[user._id].kp;
}
startRelayConnection();
}
@ -786,30 +798,37 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
const changed = (node.ssh == null);
if (node.ssh == null) { node.ssh = {}; }
// Check if credentials are the same
//if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
// Clear up any existing credentials or credentials for users that don't exist anymore
for (var i in node.ssh) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.ssh[i]; } }
// Clear legacy credentials
delete node.ssh.u;
delete node.ssh.p;
delete node.ssh.k;
delete node.ssh.kp;
// Save the credentials
if (obj.password != null) {
node.ssh = { u: obj.username, p: obj.password };
node.ssh[user._id] = { u: obj.username, p: obj.password };
} else if (obj.privateKey != null) {
node.ssh = { u: obj.username, k: obj.privateKey };
if (keep == 2) { node.ssh.kp = obj.privateKeyPass; }
node.ssh[user._id] = { u: obj.username, k: obj.privateKey };
if (keep == 2) { node.ssh[user._id].kp = obj.privateKeyPass; }
} else return;
parent.parent.db.Set(node);
// Event node change if needed
if (changed) {
// Event the node change
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" };
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.
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
}
});
}
// Start the looppback server
function startRelayConnection(authCookie) {
try {
@ -1032,22 +1051,22 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
ws._socket.resume();
// Check if we have SSH credentials for this device
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'))) {
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'))) {
// Send a request for SSH authentication
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
} else if ((typeof node.ssh.k == 'string') && (typeof node.ssh.kp != 'string')) {
} else if ((typeof node.ssh[user._id].k == 'string') && (typeof node.ssh[user._id].kp != 'string')) {
// Send a request for SSH authentication with option for only the private key password
obj.username = node.ssh.u;
obj.privateKey = node.ssh.k;
obj.username = node.ssh[user._id].u;
obj.privateKey = node.ssh[user._id].k;
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
} else {
// Use our existing credentials
obj.username = node.ssh.u;
if (typeof node.ssh.p == 'string') {
obj.password = node.ssh.p;
} else if (typeof node.ssh.k == 'string') {
obj.privateKey = node.ssh.k;
obj.privateKeyPass = node.ssh.kp;
obj.username = node.ssh[user._id].u;
if (typeof node.ssh[user._id].p == 'string') {
obj.password = node.ssh[user._id].p;
} else if (typeof node.ssh[user._id].k == 'string') {
obj.privateKey = node.ssh[user._id].k;
obj.privateKeyPass = node.ssh[user._id].kp;
}
try { ws.send(JSON.stringify({ action: 'sshautoauth' })) } catch (ex) { }
}
@ -1132,30 +1151,37 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
parent.parent.db.Get(obj.nodeid, function (err, nodes) {
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
const changed = (node.ssh == null);
if (node.rdp == null) { node.rdp = {}; }
// Check if credentials are the same
//if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
//if ((typeof node.ssh[obj.userid] == 'object') && (node.ssh[obj.userid].u == obj.username) && (node.ssh[obj.userid].p == obj.password)) return; // TODO
// Clear up any existing credentials or credentials for users that don't exist anymore
for (var i in node.ssh) { if (!i.startsWith('user/') || (parent.users[i] == null)) { delete node.ssh[i]; } }
// Clear legacy credentials
delete node.ssh.u;
delete node.ssh.p;
delete node.ssh.k;
delete node.ssh.kp;
// Save the credentials
if (obj.password != null) {
node.ssh = { u: obj.username, p: obj.password };
node.ssh[user._id] = { u: obj.username, p: obj.password };
} else if (obj.privateKey != null) {
node.ssh = { u: obj.username, k: obj.privateKey };
if (keep == 2) { node.ssh.kp = obj.privateKeyPass; }
node.ssh[user._id] = { u: obj.username, k: obj.privateKey };
if (keep == 2) { node.ssh[user._id].kp = obj.privateKeyPass; }
} else return;
parent.parent.db.Set(node);
// Event node change if needed
if (changed) {
// Event the node change
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" };
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.
parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(node.meshid, [obj.nodeid]), obj, event);
}
});
}
// Start the looppback server
function startRelayConnection(authCookie) {
try {
@ -1554,22 +1580,22 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
ws._socket.resume();
// Check if we have SSH credentials for this device
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'))) {
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'))) {
// Send a request for SSH authentication
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
} else if ((typeof node.ssh.k == 'string') && (typeof node.ssh.kp != 'string')) {
} else if ((typeof node.ssh[user._id].k == 'string') && (typeof node.ssh[user._id].kp != 'string')) {
// Send a request for SSH authentication with option for only the private key password
obj.username = node.ssh.u;
obj.privateKey = node.ssh.k;
obj.username = node.ssh[user._id].u;
obj.privateKey = node.ssh[user._id].k;
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
} else {
// Use our existing credentials
obj.username = node.ssh.u;
if (typeof node.ssh.p == 'string') {
obj.password = node.ssh.p;
} else if (typeof node.ssh.k == 'string') {
obj.privateKey = node.ssh.k;
obj.privateKeyPass = node.ssh.kp;
obj.username = node.ssh[user._id].u;
if (typeof node.ssh[user._id].p == 'string') {
obj.password = node.ssh[user._id].p;
} else if (typeof node.ssh[user._id].k == 'string') {
obj.privateKey = node.ssh[user._id].k;
obj.privateKeyPass = node.ssh[user._id].kp;
}
// Create a mesh relay authentication cookie

View File

@ -1,5 +1,7 @@
## Websockets Video
Make sure you understand how MeshCentral works with your browser using chrome developer tools.
<div class="video-wrapper">
<iframe width="320" height="180" src="https://www.youtube.com/embed/3vI4URd3VzU" frameborder="0" allowfullscreen></iframe>
</div>
@ -97,5 +99,3 @@ Of course, this is just for debugging.
<https://serverurl/meshagents> aka trying figure out what this is
![ID](images/determine-id.png)
## General server statistics related

View File

@ -2693,8 +2693,8 @@ function CreateMeshCentralServer(config, args) {
// List of possible mesh agent install scripts
const meshToolsList = {
'MeshCentralRouter': { localname: 'MeshCentralRouter.exe', dlname: 'winrouter' },
'MeshCentralAssistant': { localname: 'MeshCentralAssistant.exe', dlname: 'winassistant', winhash: true },
'MeshCentralRouterMacOS': { localname: 'MeshCentralRouter.dmg', dlname: 'MeshCentralRouter.dmg' }
'MeshCentralAssistant': { localname: 'MeshCentralAssistant.exe', dlname: 'winassistant', winhash: true }
//'MeshCentralRouterMacOS': { localname: 'MeshCentralRouter.dmg', dlname: 'MeshCentralRouter.dmg' }
};
// Update the list of available mesh agents

View File

@ -423,10 +423,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
else if (event == 'updatefiles') { updateUserFiles(user, ws, domain); }
else {
// If updating guest device shares, if we are updating a user that is not creator of the share, remove the URL.
if ((event.action == 'deviceShareUpdate') && (Array.isArray(event.deviceShares))) {
if (((event.action == 'deviceShareUpdate') && (Array.isArray(event.deviceShares))) || ((event.action == 'changenode') && (event.node != null) && ((event.node.rdp != null) || (event.node.ssh != null)))) {
event = common.Clone(event);
if ((event.action == 'deviceShareUpdate') && (Array.isArray(event.deviceShares))) {
for (var i in event.deviceShares) { if (event.deviceShares[i].userid != user._id) { delete event.deviceShares[i].url; } }
}
if ((event.action == 'changenode') && (event.node != null) && ((event.node.rdp != null) || (event.node.ssh != null))) {
// Clean up RDP & SSH credentials
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; }
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; }
}
}
// This is a MeshCentral Satellite message
if (event.action == 'satellite') { if ((obj.ws.satelliteFlags & event.satelliteFlags) != 0) { try { ws.send(JSON.stringify(event)); } catch (ex) { } return; } }
@ -730,18 +737,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Remove SSH credentials if present
if (docs[i].ssh != null) {
if (docs[i].ssh.u) {
if (docs[i].ssh.k && docs[i].ssh.kp) { docs[i].ssh = 2; } // Username, key and password
else if (docs[i].ssh.k) { docs[i].ssh = 3; } // Username and key. No password.
else if (docs[i].ssh.p) { docs[i].ssh = 1; } // Username and password
if ((docs[i].ssh[obj.user._id] != null) && (docs[i].ssh[obj.user._id].u)) {
if (docs[i].ssh.k && docs[i].ssh[obj.user._id].kp) { docs[i].ssh = 2; } // Username, key and password
else if (docs[i].ssh[obj.user._id].k) { docs[i].ssh = 3; } // Username and key. No password.
else if (docs[i].ssh[obj.user._id].p) { docs[i].ssh = 1; } // Username and password
else { delete docs[i].ssh; }
} else {
delete docs[i].ssh;
}
}
// Remove RDP credentials if present
if (docs[i].rdp != null) { docs[i].rdp = 1; }
// Remove RDP credentials if present, only set to 1 if our userid has RDP credentials
if ((docs[i].rdp != null) && (docs[i].rdp[obj.user._id] != null)) { docs[i].rdp = 1; } else { delete docs[i].rdp; }
// Remove Intel AMT credential if present
if (docs[i].intelamt != null) {
@ -3014,13 +3021,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
}
if ((typeof command.ssh == 'number') && (command.ssh == 0)) {
if (node.ssh != null) { delete node.ssh; change = 1; changes.push('ssh'); } // Delete the SSH cendentials
if ((node.ssh != null) && (node.ssh[user._id] != null)) { delete node.ssh[user._id]; change = 1; changes.push('ssh'); } // Delete the SSH cendentials
}
if ((typeof command.rdp == 'number') && (command.rdp == 0)) {
if (node.rdp != null) { delete node.rdp; change = 1; changes.push('rdp'); } // Delete the RDP cendentials
if ((node.rdp != null) && (node.rdp[user._id] != null)) { delete node.rdp[user._id]; change = 1; changes.push('rdp'); } // Delete the RDP cendentials
}
// Clean up any legacy RDP and SSH credentials
if (node.rdp != null) { delete node.rdp.d; delete node.rdp.u; delete node.rdp.p; }
if (node.ssh != null) { delete node.ssh.u; delete node.ssh.p; delete node.ssh.k; delete node.ssh.kp; }
if (domain.geolocation && command.userloc && ((node.userloc == null) || (command.userloc[0] != node.userloc[0]) || (command.userloc[1] != node.userloc[1]))) {
change = 1;
if ((command.userloc.length == 0) && (node.userloc)) {

View File

@ -1183,6 +1183,8 @@
},
{
"en": ", SFTP",
"nl": ", SFTP",
"pl": ", SFTP",
"xloc": [
"default-mobile.handlebars->11->468",
"default.handlebars->39->1328"
@ -1190,6 +1192,8 @@
},
{
"en": ", SSH",
"nl": ", SSH",
"pl": ", SSH",
"xloc": [
"default.handlebars->39->1296"
]
@ -11437,7 +11441,7 @@
{
"en": "Browser Size",
"nl": "Browser grootte",
"pl": "Rozmiar Przeglądarki",
"pl": "Jak Okna Przeglądarki",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize->3"
]
@ -12148,7 +12152,7 @@
{
"en": "Canvas Size",
"nl": "Canvas grootte",
"pl": "Rozmiar Zakrycia",
"pl": "Okno Robocze",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize->1"
]
@ -20887,7 +20891,7 @@
{
"en": "Disable Cursor Settings",
"nl": "Cursorinstellingen uitschakelen",
"pl": "Wyłączenie Ustawień Kursora",
"pl": "Wyłącz Ustawienia Kursora",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->11"
]
@ -20895,7 +20899,7 @@
{
"en": "Disable Cursor Shadow",
"nl": "Cursorschaduw uitschakelen",
"pl": "Wyłączenie Cienia Kursora",
"pl": "Wyłącz Cień Kursora",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->9"
]
@ -20903,7 +20907,7 @@
{
"en": "Disable Full Window Drag",
"nl": "Volledig venster slepen uitschakelen",
"pl": "Wyłączenie Przenoszenie Całego Okna",
"pl": "Wyłącz Przeciąganie Okna z Podglądem",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->3"
]
@ -20911,7 +20915,7 @@
{
"en": "Disable Menu Animations",
"nl": "Menu animaties uitschakelen",
"pl": "Wyłączenie Animacji Menu",
"pl": "Wyłącz Animację Menu",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->5"
]
@ -20919,7 +20923,7 @@
{
"en": "Disable Theming",
"nl": "Thema's uitschakelen",
"pl": "Wyłączenie Tematów Wizualnych",
"pl": "Wyłącz Temat Wizualny",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->7"
]
@ -20927,7 +20931,7 @@
{
"en": "Disable Wallpaper",
"nl": "Achtergrond uitschakelen",
"pl": "Wyłączenie Tapety",
"pl": "Wyłącz Tapetę Pulpitu",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->5->d7rdpflags->1"
]
@ -21211,7 +21215,7 @@
{
"en": "Display Size",
"nl": "Scherm grootte",
"pl": "Rozmiar Wyświetlacza",
"pl": "Rozdzielczość Wyświetlacza",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->1"
]
@ -26265,7 +26269,7 @@
"ja": "速い",
"ko": "빠른",
"nl": "Snel",
"pl": "Szybko",
"pl": "Duża",
"pt": "Rápido",
"pt-br": "Rápido",
"ru": "Быстро",
@ -27393,7 +27397,7 @@
"ja": "フレームレート",
"ko": "프레임 속도",
"nl": "Frameverhouding",
"pl": "Liczba klatek na sekundę",
"pl": "Prędkość odświeżania",
"pt": "Taxa de quadros",
"pt-br": "Taxa de quadros",
"ru": "Частота кадров",
@ -36863,12 +36867,16 @@
},
{
"en": "Local network connection thru a relay agent.",
"nl": "Lokale netwerkverbinding via een relay-agent.",
"pl": "Lokalne połączenie sieciowe za pośrednictwem przekierowania agenta.",
"xloc": [
"default.handlebars->39->384"
]
},
{
"en": "Local network connection.",
"nl": "Lokale netwerkverbinding.",
"pl": "Lokalne połączenie sieciowe.",
"xloc": [
"default.handlebars->39->386"
]
@ -37110,7 +37118,7 @@
"it": "Blocca su Disconnessione",
"ja": "ロックオン切断",
"nl": "Vergrendelen bij verbreken",
"pl": "Zablokuj na Odłącz",
"pl": "Zablokuj po Odłączeniu",
"pt-br": "Bloquear ao Desconectar",
"ru": "Заблокировать при отключении",
"tr": "Bağlantıyı Keste Kilitle",
@ -39003,7 +39011,7 @@
"ja": "中",
"ko": "중간",
"nl": "Gemiddeld",
"pl": "Średnio",
"pl": "Średnia",
"pt": "Médio",
"pt-br": "Médio",
"ru": "Средний",
@ -49028,7 +49036,7 @@
{
"en": "RDP Connect",
"nl": "RDP verbinden",
"pl": "Połącz za pomocą RDP",
"pl": "Połącz (protokół RDP)",
"xloc": [
"default.handlebars->container->column_l->p11->deskarea0->deskarea1->3->connectbutton1rspan"
]
@ -50034,6 +50042,7 @@
},
{
"en": "Remember password",
"pl": "Zapamiętaj hasło",
"nl": "Onthoud wachtwoord",
"xloc": [
"default-mobile.handlebars->11->461",
@ -50115,6 +50124,7 @@
{
"en": "Remember user & key",
"nl": "Onthoud gebruikeruser & sleutel",
"pl": "Zapamiętaj użytkownika i klucz",
"xloc": [
"default-mobile.handlebars->11->460",
"default.handlebars->39->1311",
@ -53671,6 +53681,8 @@
},
{
"en": "SFTP Connect",
"nl": "SFTP verbinding",
"pl": "Połącz z SFTP",
"xloc": [
"default-mobile.handlebars->container->page_content->column_l->p10->p10files->p13toolbar->1->0->1->3",
"default.handlebars->container->column_l->p13->p13toolbar->1->0->1->3"
@ -53956,6 +53968,8 @@
},
{
"en": "SSH Connect",
"nl": "SSH verbinding",
"pl": "Połącz z SSH",
"xloc": [
"default-mobile.handlebars->container->page_content->column_l->p10->p10terminal->termTable->termarea1->1->3->connectbutton2sspan",
"default.handlebars->container->column_l->p12->termTable->1->1->0->1->3->connectbutton2sspan"
@ -54083,6 +54097,7 @@
{
"en": "SSH-User+Key",
"nl": "SSH-gebruiker+sleutel",
"pl": "SSH-Uużytkownik+Klucz",
"xloc": [
"default-mobile.handlebars->11->324",
"default-mobile.handlebars->11->328",
@ -54093,6 +54108,7 @@
{
"en": "SSH-User+Key+Pass",
"nl": "SSH-gebruiker+sleutel+wachtwoord",
"pl": "SSH-Uużytkownik+Klucz+Hasło",
"xloc": [
"default-mobile.handlebars->11->323",
"default-mobile.handlebars->11->327",
@ -54103,6 +54119,7 @@
{
"en": "SSH-User+Pass",
"nl": "SSH-gebruiker+wachtwoord",
"pl": "SSH-Uużytkownik+Hasło",
"xloc": [
"default-mobile.handlebars->11->322",
"default-mobile.handlebars->11->326",
@ -54589,7 +54606,7 @@
{
"en": "Screen Size",
"nl": "Scherm grootte",
"pl": "Rozmiar Ekranu",
"pl": "Jak Całego Ekranu",
"xloc": [
"default.handlebars->container->dialog->dialogBody->dialog7->d7rdpkvm->3->d7rdpsize->5"
]
@ -58727,7 +58744,7 @@
"ja": "スロー",
"ko": "느린",
"nl": "Traag",
"pl": "Powoli",
"pl": "Mała",
"pt": "Lento",
"pt-br": "Lento",
"ru": "Медленно",
@ -60543,6 +60560,7 @@
{
"en": "Stored Key",
"nl": "Opgeslagen sleutel",
"pl": "Przechowywany Klucz",
"xloc": [
"default-mobile.handlebars->11->448",
"default.handlebars->39->1299",
@ -60803,7 +60821,7 @@
"ja": "マウスボタンを交換する",
"ko": "마우스 버튼 교체",
"nl": "Wissel muisknoppen",
"pl": "Zamień Przyciski Myszy",
"pl": "Zamień Strony Przycisków Myszy",
"pt": "Botões de troca do mouse",
"pt-br": "Trocar botões do mouse",
"ru": "Поменять местами кнопки мыши",
@ -68120,7 +68138,7 @@
"ja": "非常に遅い",
"ko": "아주 느린",
"nl": "Erg traag",
"pl": "Bardzo powoli",
"pl": "Bardzo mała",
"pt": "Muito devagar",
"pt-br": "Muito lento",
"ru": "Очень медленно",

View File

@ -5132,7 +5132,7 @@
if (serverinfo.https == true) { portStr = (serverinfo.port == 443)?'':(':' + serverinfo.port); } else { portStr = (serverinfo.port == 80) ? '' : (':' + serverinfo.port); }
// Add Linux/macOS binary installer option
var binaryInstallAgentsOrder = [ 6, 5, 10005, 25, 26, 28, 30, 32, 37, 47, 40, 41 ];
var binaryInstallAgentsOrder = [ 6, 5, 10005, 25, 26, 28, 30, 32, 37, 40, 41 ];
var binaryInstallAgents = { 5 : 'Linux x86-32', 6 : 'Linux x86-64', 10005 : 'Apple OSX Universal', 25 : 'Linux ARM-HF, Rasberry Pi', 26 : 'Linux ARM64-HF', 28: 'Linux MIPS24KC (OpenWRT)', 30 : 'FreeBSD x86-64', 32: 'Linux ARM 64 bit (glibc/2.24 NOKVM)', 36: 'OpenWRT x86-64', 37: 'OpenBSD x86-64', 40: 'Linux MIPSEL24KC (OpenWRT)', 41: 'ARMADA/CORTEX-A53/MUSL (OpenWRT)' };
for (var i in binaryInstallAgentsOrder) { moreoptions += '<option value=' + binaryInstallAgentsOrder[i] + '>' + binaryInstallAgents[binaryInstallAgentsOrder[i]] + '</option>' }
x += '<div id=aginsSysTypeDiv>';

View File

@ -7533,12 +7533,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
if ((r.pmt != null) || (r.ssh != null) || (r.rdp != null) || ((r.intelamt != null) && ((r.intelamt.pass != null) || (r.intelamt.mpspass != null)))) {
r = Object.assign({}, r); // Shallow clone
if (r.pmt != null) { r.pmt = 1; }
if (r.ssh && r.ssh.u) {
if (r.ssh.p) { r.ssh = 1; } // Username and password
else if (r.ssh.k && r.ssh.kp) { r.ssh = 2; } // Username, key and password
else if (r.ssh.k) { r.ssh = 3; } // Username and key. No password.
if (r.ssh != null) {
var n = {};
for (var i in r.ssh) {
if (i.startsWith('user/')) {
if (r.ssh[i].p) { n[i] = 1; } // Username and password
else if (r.ssh[i].k && r.ssh[i].kp) { n[i] = 2; } // Username, key and password
else if (r.ssh[i].k) { n[i] = 3; } // Username and key. No password.
}
if (r.rdp != null) { r.rdp = 1; }
}
r.ssh = n;
}
if (r.rdp != null) { var n = {}; for (var i in r.rdp) { if (i.startsWith('user/')) { n[i] = 1; } } r.rdp = n; }
if ((r.intelamt != null) && ((r.intelamt.pass != null) || (r.intelamt.mpspass != null))) {
r.intelamt = Object.assign({}, r.intelamt); // Shallow clone
if (r.intelamt.pass != null) { r.intelamt.pass = 1; }; // Remove the Intel AMT administrator password from the node