mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-22 13:21:31 +03:00
Many server improvements, wildcard certs, local keyboard map, improved object cleanup, limited input mode.
This commit is contained in:
parent
eb3977ee72
commit
92b9a9d5be
@ -34,6 +34,7 @@ var MESHRIGHT_REMOTEVIEW = 256;
|
||||
var MESHRIGHT_NOTERMINAL = 512;
|
||||
var MESHRIGHT_NOFILES = 1024;
|
||||
var MESHRIGHT_NOAMT = 2048;
|
||||
var MESHRIGHT_LIMITEDINPUT = 4096;
|
||||
|
||||
function createMeshCore(agent) {
|
||||
var obj = {};
|
||||
@ -772,12 +773,12 @@ function createMeshCore(agent) {
|
||||
};
|
||||
if (this.httprequest.desktop.kvm.hasOwnProperty("connectionCount")) { this.httprequest.desktop.kvm.connectionCount++; } else { this.httprequest.desktop.kvm.connectionCount = 1; }
|
||||
|
||||
//sendConsoleText('KVM Rights: ' + this.httprequest.rights);
|
||||
if ((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) {
|
||||
if ((this.httprequest.rights == 0xFFFFFFFF) || (((this.httprequest.rights & MESHRIGHT_REMOTECONTROL) != 0) && ((this.httprequest.rights & MESHRIGHT_REMOTEVIEW) == 0))) {
|
||||
// If we have remote control rights, pipe the KVM input
|
||||
this.pipe(this.httprequest.desktop.kvm, { dataTypeSkip: 1, end: false }); // 0 = Binary, 1 = Text. Pipe the Browser --> KVM input.
|
||||
} else {
|
||||
// We need to only pipe non-mouse & non-keyboard inputs.
|
||||
//sendConsoleText('Warning: No Remote Desktop Input Rights.');
|
||||
// TODO!!!
|
||||
}
|
||||
|
||||
|
2
agents/meshcore.min.js
vendored
2
agents/meshcore.min.js
vendored
File diff suppressed because one or more lines are too long
@ -8,7 +8,7 @@
|
||||
# Description: <DESCRIPTION>
|
||||
### END INIT INFO
|
||||
|
||||
SCRIPT=/usr/local/mesh_services/meshagent/meshagent
|
||||
SCRIPT=/usr/local/mesh/meshagent
|
||||
RUNAS=root
|
||||
|
||||
PIDFILE=/var/run/meshagent.pid
|
||||
|
@ -171,6 +171,20 @@ module.exports.CertificateOperations = function (parent) {
|
||||
return str.split('\r').join('\n'); // If there is no \n, replace all \r with \n.
|
||||
}
|
||||
|
||||
// Return true if the name is found in the certificates names, we support wildcard certificates
|
||||
function compareCertificateNames(certNames, name) {
|
||||
if (certNames == null) return false;
|
||||
if (certNames.indexOf(name.toLowerCase()) >= 0) return true;
|
||||
for (var i in certNames) {
|
||||
if ((certNames[i].startsWith('*.') == true) && (name.endsWith(certNames[i].substring(1)) == true)) { return true; }
|
||||
if (certNames[i].startsWith('http://*.') == true) {
|
||||
if (name.endsWith(certNames[i].substring(8)) == true) { return true; }
|
||||
if ((certNames[i].endsWith('/') == true) && (name.endsWith(certNames[i].substring(8, certNames[i].length - 1)) == true)) { return true; }
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the web server TLS certificate and private key, if not present, create demonstration ones.
|
||||
obj.GetMeshServerCertificate = function (args, config, func) {
|
||||
var i = 0;
|
||||
@ -268,55 +282,66 @@ module.exports.CertificateOperations = function (parent) {
|
||||
if (xxargs.length > 2) { mpsOrganization = xxargs[2]; }
|
||||
}
|
||||
|
||||
if (rcount === rcountmax) {
|
||||
// Fetch the certificates names for the main certificate
|
||||
r.AmtMpsName = obj.pki.certificateFromPem(r.mps.cert).subject.getField("CN").value;
|
||||
var webCertificate = obj.pki.certificateFromPem(r.web.cert);
|
||||
r.WebIssuer = webCertificate.issuer.getField("CN").value;
|
||||
r.CommonName = webCertificate.subject.getField("CN").value;
|
||||
if (r.CommonName.startsWith('*.')) {
|
||||
if (commonName.indexOf('.') == -1) { console.log("ERROR: Must specify a server full domain name in Config.json->Settings->Cert when using a wildcard certificate."); process.exit(0); return; }
|
||||
if (commonName.startsWith('*.')) { console.log("ERROR: Server can't use a wildcard name: " + commonName); process.exit(0); return; }
|
||||
r.CommonName = commonName;
|
||||
}
|
||||
r.CommonNames = [r.CommonName.toLowerCase()];
|
||||
var altNames = webCertificate.getExtension("subjectAltName");
|
||||
if (altNames) { for (i = 0; i < altNames.altNames.length; i++) { r.CommonNames.push(altNames.altNames[i].value.toLowerCase()); } }
|
||||
var rootCertificate = obj.pki.certificateFromPem(r.root.cert);
|
||||
r.RootName = rootCertificate.subject.getField("CN").value;
|
||||
}
|
||||
|
||||
// Look for domains that have DNS names and load their certificates
|
||||
r.dns = {};
|
||||
for (i in config.domains) {
|
||||
if ((i != "") && (config.domains[i] != null) && (config.domains[i].dns != null)) {
|
||||
dnsname = config.domains[i].dns;
|
||||
if (args.tlsoffload) {
|
||||
// If the web certificate already exist, load it. Load just the certificate since we are in TLS offload situation
|
||||
if (obj.fileExists("webserver-" + i + "-cert-public.crt")) {
|
||||
r.dns[i] = { cert: obj.fileLoad("webserver-" + i + "-cert-public.crt", "utf8") };
|
||||
config.domains[i].certs = r.dns[i];
|
||||
} else {
|
||||
console.log("WARNING: File \"webserver-" + i + "-cert-public.crt\" missing, domain \"" + i + "\" will not work correctly.");
|
||||
}
|
||||
// Check if this domain matches a parent wildcard cert, if so, use the parent cert.
|
||||
if (compareCertificateNames(r.CommonNames, dnsname) == true) {
|
||||
r.dns[i] = { cert: obj.fileLoad("webserver-cert-public.crt", "utf8"), key: obj.fileLoad("webserver-cert-private.key", "utf8") };
|
||||
} else {
|
||||
// If the web certificate already exist, load it. Load both certificate and private key
|
||||
if (obj.fileExists("webserver-" + i + "-cert-public.crt") && obj.fileExists("webserver-" + i + "-cert-private.key")) {
|
||||
r.dns[i] = { cert: obj.fileLoad("webserver-" + i + "-cert-public.crt", "utf8"), key: obj.fileLoad("webserver-" + i + "-cert-private.key", "utf8") };
|
||||
config.domains[i].certs = r.dns[i];
|
||||
// If CA certificates are present, load them
|
||||
caindex = 1;
|
||||
r.dns[i].ca = [];
|
||||
do {
|
||||
caok = false;
|
||||
if (obj.fileExists("webserver-" + i + "-cert-chain" + caindex + ".crt")) {
|
||||
r.dns[i].ca.push(obj.fileLoad("webserver-" + i + "-cert-chain" + caindex + ".crt", "utf8"));
|
||||
caok = true;
|
||||
}
|
||||
caindex++;
|
||||
} while (caok === true);
|
||||
if (args.tlsoffload) {
|
||||
// If the web certificate already exist, load it. Load just the certificate since we are in TLS offload situation
|
||||
if (obj.fileExists("webserver-" + i + "-cert-public.crt")) {
|
||||
r.dns[i] = { cert: obj.fileLoad("webserver-" + i + "-cert-public.crt", "utf8") };
|
||||
config.domains[i].certs = r.dns[i];
|
||||
} else {
|
||||
console.log("WARNING: File \"webserver-" + i + "-cert-public.crt\" missing, domain \"" + i + "\" will not work correctly.");
|
||||
}
|
||||
} else {
|
||||
rcountmax++; // This certificate must be generated
|
||||
// If the web certificate already exist, load it. Load both certificate and private key
|
||||
if (obj.fileExists("webserver-" + i + "-cert-public.crt") && obj.fileExists("webserver-" + i + "-cert-private.key")) {
|
||||
r.dns[i] = { cert: obj.fileLoad("webserver-" + i + "-cert-public.crt", "utf8"), key: obj.fileLoad("webserver-" + i + "-cert-private.key", "utf8") };
|
||||
config.domains[i].certs = r.dns[i];
|
||||
// If CA certificates are present, load them
|
||||
caindex = 1;
|
||||
r.dns[i].ca = [];
|
||||
do {
|
||||
caok = false;
|
||||
if (obj.fileExists("webserver-" + i + "-cert-chain" + caindex + ".crt")) {
|
||||
r.dns[i].ca.push(obj.fileLoad("webserver-" + i + "-cert-chain" + caindex + ".crt", "utf8"));
|
||||
caok = true;
|
||||
}
|
||||
caindex++;
|
||||
} while (caok === true);
|
||||
} else {
|
||||
rcountmax++; // This certificate must be generated
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rcount === rcountmax) {
|
||||
// Fetch the Intel AMT MPS common name
|
||||
r.AmtMpsName = obj.pki.certificateFromPem(r.mps.cert).subject.getField("CN").value;
|
||||
// Fetch the name of the server
|
||||
var webCertificate = obj.pki.certificateFromPem(r.web.cert);
|
||||
r.WebIssuer = webCertificate.issuer.getField("CN").value;
|
||||
r.CommonName = webCertificate.subject.getField("CN").value;
|
||||
r.CommonNames = [r.CommonName.toLowerCase()];
|
||||
var altNames = webCertificate.getExtension("subjectAltName");
|
||||
if (altNames) { for (i = 0; i < altNames.altNames.length; i++) { r.CommonNames.push(altNames.altNames[i].value.toLowerCase()); } }
|
||||
var rootCertificate = obj.pki.certificateFromPem(r.root.cert);
|
||||
r.RootName = rootCertificate.subject.getField("CN").value;
|
||||
|
||||
if ((certargs == null) && (mpscertargs == null)) { if (func != undefined) { func(r); } return r; } // If no certificate arguments are given, keep the certificate
|
||||
var xcountry, xcountryField = webCertificate.subject.getField("C");
|
||||
if (xcountryField != null) { xcountry = xcountryField.value; }
|
||||
@ -325,14 +350,13 @@ module.exports.CertificateOperations = function (parent) {
|
||||
if (certargs == null) { commonName = r.CommonName; country = xcountry; organization = xorganization; }
|
||||
|
||||
// Check if we have correct certificates
|
||||
if ((r.CommonNames.indexOf(commonName.toLowerCase()) >= 0) && (r.AmtMpsName == mpsCommonName)) {
|
||||
// Certificate matches what we want, keep it.
|
||||
if (compareCertificateNames(r.CommonNames, commonName) == false) { forceWebCertGen = 1; }
|
||||
if (r.AmtMpsName != mpsCommonName) { forceMpsCertGen = 1; }
|
||||
|
||||
// If the certificates matches what we want, use them.
|
||||
if ((forceWebCertGen == 0) && (forceMpsCertGen == 0)) {
|
||||
if (func !== undefined) { func(r); }
|
||||
return r;
|
||||
} else {
|
||||
// Check what certificates we really need to re-generate.
|
||||
if ((r.CommonNames.indexOf(commonName.toLowerCase()) < 0)) { forceWebCertGen = 1; }
|
||||
if (r.AmtMpsName != mpsCommonName) { forceMpsCertGen = 1; }
|
||||
}
|
||||
}
|
||||
if (parent.configurationFiles != null) { console.log("Error: Database missing some certificates."); process.exit(0); return null; }
|
||||
@ -418,33 +442,53 @@ module.exports.CertificateOperations = function (parent) {
|
||||
|
||||
r = { root: { cert: rootCertificate, key: rootPrivateKey }, web: { cert: webCertificate, key: webPrivateKey, ca: [] }, mps: { cert: mpsCertificate, key: mpsPrivateKey }, agent: { cert: agentCertificate, key: agentPrivateKey }, ca: calist, CommonName: commonName, RootName: rootName, AmtMpsName: mpsCommonName, dns: {}, WebIssuer: webIssuer };
|
||||
|
||||
// Fetch the certificates names for the main certificate
|
||||
var webCertificate = obj.pki.certificateFromPem(r.web.cert);
|
||||
r.WebIssuer = webCertificate.issuer.getField("CN").value;
|
||||
r.CommonName = webCertificate.subject.getField("CN").value;
|
||||
if (r.CommonName.startsWith('*.')) {
|
||||
if (commonName.indexOf('.') == -1) { console.log("ERROR: Must specify a server full domain name in Config.json->Settings->Cert when using a wildcard certificate."); process.exit(0); return; }
|
||||
if (commonName.startsWith('*.')) { console.log("ERROR: Server can't use a wildcard name: " + commonName); process.exit(0); return; }
|
||||
r.CommonName = commonName;
|
||||
}
|
||||
r.CommonNames = [r.CommonName.toLowerCase()];
|
||||
var altNames = webCertificate.getExtension("subjectAltName");
|
||||
if (altNames) { for (i = 0; i < altNames.altNames.length; i++) { r.CommonNames.push(altNames.altNames[i].value.toLowerCase()); } }
|
||||
var rootCertificate = obj.pki.certificateFromPem(r.root.cert);
|
||||
r.RootName = rootCertificate.subject.getField("CN").value;
|
||||
|
||||
// Look for domains with DNS names that have no certificates and generated them.
|
||||
for (i in config.domains) {
|
||||
if ((i != "") && (config.domains[i] != null) && (config.domains[i].dns != null)) {
|
||||
dnsname = config.domains[i].dns;
|
||||
if (!args.tlsoffload) {
|
||||
// If the web certificate does not exist, create it
|
||||
if ((obj.fileExists("webserver-" + i + "-cert-public.crt") === false) || (obj.fileExists("webserver-" + i + "-cert-private.key") === false)) {
|
||||
console.log("Generating HTTPS certificate for " + i + "...");
|
||||
var xwebCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, dnsname, country, organization, null, strongCertificate);
|
||||
var xwebCertificate = obj.pki.certificateToPem(xwebCertAndKey.cert);
|
||||
var xwebPrivateKey = obj.pki.privateKeyToPem(xwebCertAndKey.key);
|
||||
obj.fs.writeFileSync(parent.getConfigFilePath("webserver-" + i + "-cert-public.crt"), xwebCertificate);
|
||||
obj.fs.writeFileSync(parent.getConfigFilePath("webserver-" + i + "-cert-private.key"), xwebPrivateKey);
|
||||
r.dns[i] = { cert: xwebCertificate, key: xwebPrivateKey };
|
||||
config.domains[i].certs = r.dns[i];
|
||||
// Check if this domain matches a parent wildcard cert, if so, use the parent cert.
|
||||
if (compareCertificateNames(r.CommonNames, dnsname) == true) {
|
||||
r.dns[i] = { cert: obj.fileLoad("webserver-cert-public.crt", "utf8"), key: obj.fileLoad("webserver-cert-private.key", "utf8") };
|
||||
} else {
|
||||
if (!args.tlsoffload) {
|
||||
// If the web certificate does not exist, create it
|
||||
if ((obj.fileExists("webserver-" + i + "-cert-public.crt") === false) || (obj.fileExists("webserver-" + i + "-cert-private.key") === false)) {
|
||||
console.log("Generating HTTPS certificate for " + i + "...");
|
||||
var xwebCertAndKey = obj.IssueWebServerCertificate(rootCertAndKey, false, dnsname, country, organization, null, strongCertificate);
|
||||
var xwebCertificate = obj.pki.certificateToPem(xwebCertAndKey.cert);
|
||||
var xwebPrivateKey = obj.pki.privateKeyToPem(xwebCertAndKey.key);
|
||||
obj.fs.writeFileSync(parent.getConfigFilePath("webserver-" + i + "-cert-public.crt"), xwebCertificate);
|
||||
obj.fs.writeFileSync(parent.getConfigFilePath("webserver-" + i + "-cert-private.key"), xwebPrivateKey);
|
||||
r.dns[i] = { cert: xwebCertificate, key: xwebPrivateKey };
|
||||
config.domains[i].certs = r.dns[i];
|
||||
|
||||
// If CA certificates are present, load them
|
||||
caindex = 1;
|
||||
r.dns[i].ca = [];
|
||||
do {
|
||||
caok = false;
|
||||
if (obj.fileExists("webserver-" + i + "-cert-chain" + caindex + ".crt")) {
|
||||
r.dns[i].ca.push(fixEndOfLines(obj.fs.readFileSync(parent.getConfigFilePath("webserver-" + i + "-cert-chain" + caindex + ".crt"), "utf8")));
|
||||
caok = true;
|
||||
}
|
||||
caindex++;
|
||||
} while (caok === true);
|
||||
// If CA certificates are present, load them
|
||||
caindex = 1;
|
||||
r.dns[i].ca = [];
|
||||
do {
|
||||
caok = false;
|
||||
if (obj.fileExists("webserver-" + i + "-cert-chain" + caindex + ".crt")) {
|
||||
r.dns[i].ca.push(fixEndOfLines(obj.fs.readFileSync(parent.getConfigFilePath("webserver-" + i + "-cert-chain" + caindex + ".crt"), "utf8")));
|
||||
caok = true;
|
||||
}
|
||||
caindex++;
|
||||
} while (caok === true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
45
meshagent.js
45
meshagent.js
@ -18,7 +18,7 @@
|
||||
module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
const forge = parent.parent.certificateOperations.forge;
|
||||
const common = parent.parent.common;
|
||||
const agentUpdateBlockSize = 65520;
|
||||
const agentUpdateBlockSize = 65531;
|
||||
|
||||
var obj = {};
|
||||
obj.domain = domain;
|
||||
@ -45,6 +45,8 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
if ((arg == 1) || (arg == null)) { try { ws.close(); if (obj.nodeid != null) { parent.parent.debug(1, 'Soft disconnect ' + obj.nodeid + ' (' + obj.remoteaddrport + ')'); } } catch (e) { console.log(e); } } // Soft close, close the websocket
|
||||
if (arg == 2) { try { ws._socket._parent.end(); if (obj.nodeid != null) { parent.parent.debug(1, 'Hard disconnect ' + obj.nodeid + ' (' + obj.remoteaddrport + ')'); } } catch (e) { console.log(e); } } // Hard close, close the TCP socket
|
||||
// If arg == 3, don't communicate with this agent anymore, but don't disconnect (Duplicate agent).
|
||||
|
||||
// Remove this agent from the webserver list
|
||||
if (parent.wsagents[obj.dbNodeKey] == obj) {
|
||||
delete parent.wsagents[obj.dbNodeKey];
|
||||
parent.parent.ClearConnectivityState(obj.dbMeshKey, obj.dbNodeKey, 1);
|
||||
@ -53,14 +55,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Get the current mesh
|
||||
const mesh = parent.meshes[obj.dbMeshKey];
|
||||
|
||||
// Other clean up may be needed here
|
||||
if (obj.unauth) { delete obj.unauth; }
|
||||
if (obj.agentUpdate != null) {
|
||||
if (obj.agentUpdate.fd) { try { parent.fs.close(obj.agentUpdate.fd); } catch (ex) { } }
|
||||
parent.parent.taskLimiter.completed(obj.agentUpdate.taskid); // Indicate this task complete
|
||||
delete obj.agentUpdate;
|
||||
}
|
||||
|
||||
// If this is a temporary or recovery agent, or all devices in this group are temporary, remove the agent (0x20 = Temporary, 0x40 = Recovery)
|
||||
if (((obj.agentInfo) && (obj.agentInfo.capabilities) && ((obj.agentInfo.capabilities & 0x20) || (obj.agentInfo.capabilities & 0x40))) || ((mesh) && (mesh.flags) && (mesh.flags & 1))) {
|
||||
// Delete this node including network interface information and events
|
||||
@ -85,7 +79,26 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Update the last connect time
|
||||
if (obj.authenticated == 2) { db.Set({ _id: 'lc' + obj.dbNodeKey, type: 'lastconnect', domain: domain.id, time: obj.connectTime, addr: obj.remoteaddrport }); }
|
||||
}
|
||||
delete obj.nodeid;
|
||||
|
||||
// If we where updating the agent, clean that up.
|
||||
if (obj.agentUpdate != null) {
|
||||
if (obj.agentUpdate.fd) { try { parent.fs.close(obj.agentUpdate.fd); } catch (ex) { } }
|
||||
parent.parent.taskLimiter.completed(obj.agentUpdate.taskid); // Indicate this task complete
|
||||
delete obj.agentUpdate;
|
||||
}
|
||||
|
||||
// Perform aggressive cleanup
|
||||
if (obj.nonce) { delete obj.nonce; }
|
||||
if (obj.nodeid) { delete obj.nodeid; }
|
||||
if (obj.unauth) { delete obj.unauth; }
|
||||
if (obj.remoteaddr) { delete obj.remoteaddr; }
|
||||
if (obj.remoteaddrport) { delete obj.remoteaddrport; }
|
||||
if (obj.meshid) { delete obj.meshid; }
|
||||
if (obj.dbNodeKey) { delete obj.dbNodeKey; }
|
||||
if (obj.dbMeshKey) { delete obj.dbMeshKey; }
|
||||
if (obj.connectTime) { delete obj.connectTime; }
|
||||
if (obj.agentInfo) { delete obj.agentInfo; }
|
||||
ws.removeAllListeners(["message", "close", "error"]);
|
||||
};
|
||||
|
||||
// When data is received from the mesh agent web socket
|
||||
@ -112,7 +125,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
const agentMeshCoreHash = (msg.length == 52) ? msg.substring(4, 52) : null;
|
||||
|
||||
// If the agent indicates this is a custom core, we are done.
|
||||
if ((agentMeshCoreHash != null) && (agentMeshCoreHash == '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')) {
|
||||
if ((agentMeshCoreHash != null) && (agentMeshCoreHash == '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')) {
|
||||
obj.agentCoreCheck = 0;
|
||||
obj.send(common.ShortToStr(16) + common.ShortToStr(0)); // MeshCommand_CoreOk. Indicates to the agent that the core is ok. Start it if it's not already started.
|
||||
agentCoreIsStable();
|
||||
@ -197,7 +210,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
else if (cmdid == 12) { // MeshCommand_AgentHash
|
||||
if ((msg.length == 52) && (obj.agentExeInfo != null) && (obj.agentExeInfo.update == true)) {
|
||||
const agenthash = msg.substring(4);
|
||||
if ((agenthash != obj.agentExeInfo.hash) && (agenthash != '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')) {
|
||||
if ((agenthash != obj.agentExeInfo.hash) && (agenthash != '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0')) {
|
||||
// Mesh agent update required, do it using task limiter so not to flood the network. Medium priority task.
|
||||
parent.parent.taskLimiter.launch(function (argument, taskid, taskLimiterQueue) {
|
||||
if (obj.authenticated != 2) { parent.parent.taskLimiter.completed(taskid); return; } // If agent disconnection, complete and exit now.
|
||||
@ -353,13 +366,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Perform the hash signature using older swarm server certificate
|
||||
parent.parent.certificateOperations.acceleratorPerformSignature(1, msg.substring(2) + obj.nonce, obj, function (obj2, signature) {
|
||||
// Send back our certificate + signature
|
||||
obj2.send(common.ShortToStr(2) + common.ShortToStr(obj2.parent.swarmCertificateAsn1.length) + obj2.parent.swarmCertificateAsn1 + signature); // Command 2, certificate + signature
|
||||
obj2.send(common.ShortToStr(2) + common.ShortToStr(parent.swarmCertificateAsn1.length) + parent.swarmCertificateAsn1 + signature); // Command 2, certificate + signature
|
||||
});
|
||||
} else {
|
||||
// Perform the hash signature using the server agent certificate
|
||||
parent.parent.certificateOperations.acceleratorPerformSignature(0, msg.substring(2) + obj.nonce, obj, function (obj2, signature) {
|
||||
// Send back our certificate + signature
|
||||
obj2.send(common.ShortToStr(2) + common.ShortToStr(obj2.parent.agentCertificateAsn1.length) + obj2.parent.agentCertificateAsn1 + signature); // Command 2, certificate + signature
|
||||
obj2.send(common.ShortToStr(2) + common.ShortToStr(parent.agentCertificateAsn1.length) + parent.agentCertificateAsn1 + signature); // Command 2, certificate + signature
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -419,7 +432,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
});
|
||||
|
||||
// If error, do nothing
|
||||
ws.on('error', function (err) { console.log('AGENT WSERR: ' + err); });
|
||||
ws.on('error', function (err) { console.log('AGENT WSERR: ' + err); obj.close(0); });
|
||||
|
||||
// If the mesh agent web socket is closed, clean up.
|
||||
ws.on('close', function (req) {
|
||||
@ -703,7 +716,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
console.log('recoveryAgentCoreIsStable()');
|
||||
|
||||
// Close the recovery agent connection when done.
|
||||
obj.close(1);
|
||||
//obj.close(1);
|
||||
}
|
||||
|
||||
obj.sendUpdatedIntelAmtPolicy = function() {
|
||||
|
@ -60,7 +60,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
obj.serverKey = Buffer.from(obj.crypto.randomBytes(48), 'binary');
|
||||
obj.loginCookieEncryptionKey = null;
|
||||
obj.serverSelfWriteAllowed = true;
|
||||
obj.taskLimiter = obj.common.createTaskLimiterQueue(20, 20, 60); // This is a task limiter queue to smooth out server work.
|
||||
obj.taskLimiter = obj.common.createTaskLimiterQueue(50, 20, 60); // (maxTasks, maxTaskTime, cleaningInterval) This is a task limiter queue to smooth out server work.
|
||||
try { obj.currentVer = JSON.parse(obj.fs.readFileSync(obj.path.join(__dirname, 'package.json'), 'utf8')).version; } catch (e) { } // Fetch server version
|
||||
|
||||
// Setup the default configuration and files paths
|
||||
@ -877,7 +877,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
};
|
||||
obj.RemoveEventDispatch = function (ids, target) {
|
||||
obj.debug(3, 'RemoveEventDispatch', id);
|
||||
for (var i in ids) { var id = ids[i]; if (obj.eventsDispatch[id]) { var j = obj.eventsDispatch[id].indexOf(target); if (j >= 0) { obj.eventsDispatch[id].splice(j, 1); } } }
|
||||
for (var i in ids) { var id = ids[i]; if (obj.eventsDispatch[id]) { var j = obj.eventsDispatch[id].indexOf(target); if (j >= 0) { if (obj.eventsDispatch[id].length == 1) { delete obj.eventsDispatch[id]; } else { obj.eventsDispatch[id].splice(j, 1); } } } }
|
||||
};
|
||||
obj.RemoveEventDispatchId = function (id) {
|
||||
obj.debug(3, 'RemoveEventDispatchId', id);
|
||||
@ -885,7 +885,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
};
|
||||
obj.RemoveAllEventDispatch = function (target) {
|
||||
obj.debug(3, 'RemoveAllEventDispatch');
|
||||
for (var i in obj.eventsDispatch) { var j = obj.eventsDispatch[i].indexOf(target); if (j >= 0) { obj.eventsDispatch[i].splice(j, 1); } }
|
||||
for (var i in obj.eventsDispatch) { var j = obj.eventsDispatch[i].indexOf(target); if (j >= 0) { if (obj.eventsDispatch[i].length == 1) { delete obj.eventsDispatch[i]; } else { obj.eventsDispatch[i].splice(j, 1); } } }
|
||||
};
|
||||
obj.DispatchEvent = function (ids, source, event, fromPeerServer) {
|
||||
// If the database is not setup, exit now.
|
||||
@ -1148,9 +1148,9 @@ function CreateMeshCentralServer(config, args) {
|
||||
// Read meshcore.js and all .js files in the modules folder.
|
||||
var meshCore = null, modulesDir = null;
|
||||
const modulesAdd = {
|
||||
'windows-amt': 'var addedModules = [];\r\n',
|
||||
'linux-amt': 'var addedModules = [];\r\n',
|
||||
'linux-noamt': 'var addedModules = [];\r\n'
|
||||
'windows-amt': ['var addedModules = [];\r\n'],
|
||||
'linux-amt': ['var addedModules = [];\r\n'],
|
||||
'linux-noamt': ['var addedModules = [];\r\n']
|
||||
};
|
||||
|
||||
// Read the recovery core if present
|
||||
@ -1158,8 +1158,8 @@ function CreateMeshCentralServer(config, args) {
|
||||
if (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'recoverycore.js')) == true) {
|
||||
try { meshRecoveryCore = obj.fs.readFileSync(obj.path.join(__dirname, 'agents', 'recoverycore.js')).toString(); } catch (ex) { }
|
||||
if (meshRecoveryCore != null) {
|
||||
modulesAdd['windows-recovery'] = 'var addedModules = [];\r\n';
|
||||
modulesAdd['linux-recovery'] = 'var addedModules = [];\r\n';
|
||||
modulesAdd['windows-recovery'] = ['var addedModules = [];\r\n'];
|
||||
modulesAdd['linux-recovery'] = ['var addedModules = [];\r\n'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1168,8 +1168,8 @@ function CreateMeshCentralServer(config, args) {
|
||||
if (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'agentrecoverycore.js')) == true) {
|
||||
try { meshAgentRecoveryCore = obj.fs.readFileSync(obj.path.join(__dirname, 'agents', 'agentrecoverycore.js')).toString(); } catch (ex) { }
|
||||
if (meshAgentRecoveryCore != null) {
|
||||
modulesAdd['windows-agentrecovery'] = 'var addedModules = [];\r\n';
|
||||
modulesAdd['linux-agentrecovery'] = 'var addedModules = [];\r\n';
|
||||
modulesAdd['windows-agentrecovery'] = ['var addedModules = [];\r\n'];
|
||||
modulesAdd['linux-agentrecovery'] = ['var addedModules = [];\r\n'];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1184,39 +1184,39 @@ function CreateMeshCentralServer(config, args) {
|
||||
if (modulesDir[i].toLowerCase().endsWith('.js')) {
|
||||
var moduleName = modulesDir[i].substring(0, modulesDir[i].length - 3);
|
||||
if (moduleName.endsWith('.min')) { moduleName = moduleName.substring(0, moduleName.length - 4); } // Remove the ".min" for ".min.js" files.
|
||||
var moduleData = 'try { addModule("' + moduleName + '", "' + obj.escapeCodeString(obj.fs.readFileSync(obj.path.join(moduleDirPath, modulesDir[i])).toString('binary')) + '"); addedModules.push("' + moduleName + '"); } catch (e) { }\r\n';
|
||||
var moduleData = [ 'try { addModule("', moduleName, '", "', obj.escapeCodeString(obj.fs.readFileSync(obj.path.join(moduleDirPath, modulesDir[i])).toString('binary')), '"); addedModules.push("', moduleName, '"); } catch (e) { }\r\n' ];
|
||||
|
||||
// Merge this module
|
||||
// NOTE: "smbios" module makes some non-AI Linux segfault, only include for IA platforms.
|
||||
if (moduleName.startsWith('amt-') || (moduleName == 'smbios')) {
|
||||
// Add to IA / Intel AMT cores only
|
||||
modulesAdd['windows-amt'] += moduleData;
|
||||
modulesAdd['linux-amt'] += moduleData;
|
||||
modulesAdd['windows-amt'].push(...moduleData);
|
||||
modulesAdd['linux-amt'].push(...moduleData);
|
||||
} else if (moduleName.startsWith('win-')) {
|
||||
// Add to Windows cores only
|
||||
modulesAdd['windows-amt'] += moduleData;
|
||||
modulesAdd['windows-amt'].push(...moduleData);
|
||||
} else if (moduleName.startsWith('linux-')) {
|
||||
// Add to Linux cores only
|
||||
modulesAdd['linux-amt'] += moduleData;
|
||||
modulesAdd['linux-noamt'] += moduleData;
|
||||
modulesAdd['linux-amt'].push(...moduleData);
|
||||
modulesAdd['linux-noamt'].push(...moduleData);
|
||||
} else {
|
||||
// Add to all cores
|
||||
modulesAdd['windows-amt'] += moduleData;
|
||||
modulesAdd['linux-amt'] += moduleData;
|
||||
modulesAdd['linux-noamt'] += moduleData;
|
||||
modulesAdd['windows-amt'].push(...moduleData);
|
||||
modulesAdd['linux-amt'].push(...moduleData);
|
||||
modulesAdd['linux-noamt'].push(...moduleData);
|
||||
}
|
||||
|
||||
// Merge this module to recovery modules if needed
|
||||
if (modulesAdd['windows-recovery'] != null) {
|
||||
if ((moduleName == 'win-console') || (moduleName == 'win-message-pump') || (moduleName == 'win-terminal')) {
|
||||
modulesAdd['windows-recovery'] += moduleData;
|
||||
modulesAdd['windows-recovery'].push(...moduleData);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge this module to agent recovery modules if needed
|
||||
if (modulesAdd['windows-agentrecovery'] != null) {
|
||||
if ((moduleName == 'win-console') || (moduleName == 'win-message-pump') || (moduleName == 'win-terminal')) {
|
||||
modulesAdd['windows-agentrecovery'] += moduleData;
|
||||
modulesAdd['windows-agentrecovery'].push(...moduleData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1226,11 +1226,11 @@ function CreateMeshCentralServer(config, args) {
|
||||
// Merge the cores and compute the hashes
|
||||
for (var i in modulesAdd) {
|
||||
if ((i == 'windows-recovery') || (i == 'linux-recovery')) {
|
||||
obj.defaultMeshCores[i] = obj.common.IntToStr(0) + modulesAdd[i] + meshRecoveryCore;
|
||||
obj.defaultMeshCores[i] = [obj.common.IntToStr(0), ...modulesAdd[i], meshRecoveryCore].join('');
|
||||
} else if ((i == 'windows-agentrecovery') || (i == 'linux-agentrecovery')) {
|
||||
obj.defaultMeshCores[i] = obj.common.IntToStr(0) + modulesAdd[i] + meshAgentRecoveryCore;
|
||||
obj.defaultMeshCores[i] = [obj.common.IntToStr(0), ...modulesAdd[i], meshAgentRecoveryCore].join('');
|
||||
} else {
|
||||
obj.defaultMeshCores[i] = obj.common.IntToStr(0) + modulesAdd[i] + meshCore;
|
||||
obj.defaultMeshCores[i] = [obj.common.IntToStr(0), ...modulesAdd[i], meshCore].join('');
|
||||
}
|
||||
obj.defaultMeshCoresHash[i] = obj.crypto.createHash('sha384').update(obj.defaultMeshCores[i]).digest("binary");
|
||||
obj.debug(1, 'Core module ' + i + ' is ' + obj.defaultMeshCores[i].length + ' bytes.');
|
||||
@ -1247,7 +1247,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
obj.updateMeshCmdTimer = 'notset';
|
||||
obj.updateMeshCmd = function (func) {
|
||||
// Figure out where meshcmd.js is and read it.
|
||||
var meshCmd = null, meshcmdPath, moduleAdditions = 'var addedModules = [];\r\n', moduleDirPath, modulesDir = null;
|
||||
var meshCmd = null, meshcmdPath, moduleAdditions = ['var addedModules = [];\r\n'], moduleDirPath, modulesDir = null;
|
||||
if ((obj.args.minifycore !== false) && (obj.fs.existsSync(obj.path.join(obj.datapath, 'meshcmd.min.js')))) { meshcmdPath = obj.path.join(obj.datapath, 'meshcmd.min.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
|
||||
else if (obj.fs.existsSync(obj.path.join(obj.datapath, 'meshcmd.js'))) { meshcmdPath = obj.path.join(obj.datapath, 'meshcmd.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
|
||||
else if ((obj.args.minifycore !== false) && (obj.fs.existsSync(obj.path.join(__dirname, 'agents', 'meshcmd.min.js')))) { meshcmdPath = obj.path.join(__dirname, 'agents', 'meshcmd.min.js'); meshCmd = obj.fs.readFileSync(meshcmdPath).toString(); }
|
||||
@ -1268,13 +1268,14 @@ function CreateMeshCentralServer(config, args) {
|
||||
// Merge this module
|
||||
var moduleName = modulesDir[i].substring(0, modulesDir[i].length - 3);
|
||||
if (moduleName.endsWith('.min')) { moduleName = moduleName.substring(0, moduleName.length - 4); } // Remove the ".min" for ".min.js" files.
|
||||
moduleAdditions += 'try { addModule("' + moduleName + '", "' + obj.escapeCodeString(obj.fs.readFileSync(obj.path.join(moduleDirPath, modulesDir[i])).toString('binary')) + '"); addedModules.push("' + moduleName + '"); } catch (e) { }\r\n';
|
||||
moduleAdditions.push('try { addModule("', moduleName, '", "', obj.escapeCodeString(obj.fs.readFileSync(obj.path.join(moduleDirPath, modulesDir[i])).toString('binary')), '"); addedModules.push("', moduleName, '"); } catch (e) { }\r\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the new default meshcmd.js
|
||||
obj.defaultMeshCmd = moduleAdditions + meshCmd;
|
||||
moduleAdditions.push(meshCmd);
|
||||
obj.defaultMeshCmd = moduleAdditions.join('');
|
||||
//console.log('MeshCmd is ' + obj.defaultMeshCmd.length + ' bytes.'); // DEBUG, Print the merged meshcmd.js size
|
||||
//obj.fs.writeFile("C:\\temp\\meshcmd.js", obj.defaultMeshCmd.substring(4)); // DEBUG, Write merged meshcmd.js to file
|
||||
if (func != null) { func(true); }
|
||||
@ -1284,7 +1285,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
obj.updateMeshCmdTimer = null;
|
||||
obj.fs.watch(meshcmdPath, function (eventType, filename) {
|
||||
if (obj.updateMeshCmdTimer != null) { clearTimeout(obj.updateMeshCmdTimer); obj.updateMeshCmdTimer = null; }
|
||||
obj.updateMeshCmdTimer = setTimeout(function () { obj.updateMeshCmd(); /*console.log('Updated meshcmd.js.');*/ }, 5000);
|
||||
obj.updateMeshCmdTimer = setTimeout(function () { obj.updateMeshCmd(); }, 5000);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
913
meshuser.js
913
meshuser.js
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.2.9-w",
|
||||
"version": "0.2.9-z",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -31,6 +31,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
|
||||
obj.debugmode = 0;
|
||||
obj.firstUpKeys = [];
|
||||
obj.stopInput = false;
|
||||
obj.localKeyMap = true;
|
||||
|
||||
obj.sessionid = 0;
|
||||
obj.username;
|
||||
@ -377,7 +378,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
|
||||
obj.SendKeyMsg = function (action, event) {
|
||||
if (action == null) return;
|
||||
if (!event) { event = window.event; }
|
||||
if (event.code) {
|
||||
if (event.code && (obj.localKeyMap == false)) {
|
||||
// Convert "event.code" into a scancode. This works the same regardless of the keyboard language.
|
||||
// Older browsers will not support this.
|
||||
var kc = convertKeyCode(event);
|
||||
|
@ -24,6 +24,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
||||
obj.useZRLE = true;
|
||||
obj.showmouse = true;
|
||||
obj.buttonmask = 0;
|
||||
obj.localKeyMap = true;
|
||||
//obj.inbytes = 0;
|
||||
//obj.outbytes = 0;
|
||||
obj.spare = null;
|
||||
@ -634,7 +635,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
||||
function _keyevent(d, e) {
|
||||
if (!e) { e = window.event; }
|
||||
|
||||
if (e.code) {
|
||||
if (e.code && (obj.localKeyMap == false)) {
|
||||
// For new browsers, this mapping is keyboard language independent
|
||||
var k = convertAmtKeyCode(e);
|
||||
if (k != null) { obj.sendkey(k, d); }
|
||||
|
@ -311,8 +311,7 @@ module.exports.CreateSwarmServer = function (parent, db, args, certificates) {
|
||||
if (checkSwarmIpAddress(socket, obj.args.swarmallowedip) == false) { obj.stats.blockedConnect++; Debug(1, "SWARM:New blocked agent connection"); return; }
|
||||
obj.stats.connectCount++;
|
||||
|
||||
socket.tag = { first: true, clientCert: socket.getPeerCertificate(true), accumulator: "", socket: socket };
|
||||
//socket.pingTimer = setInterval(function () { obj.SendCommand(socket, LegacyMeshProtocol.PING); }, 20000);
|
||||
socket.tag = { first: true, clientCert: socket.getPeerCertificate(true), accumulator: "" };
|
||||
Debug(1, 'SWARM:New legacy agent connection');
|
||||
|
||||
if ((socket.tag.clientCert == null) || (socket.tag.clientCert.subject == null)) { obj.stats.noCertConnectCount++; } else { obj.stats.clientCertConnectCount++; }
|
||||
@ -321,12 +320,20 @@ module.exports.CreateSwarmServer = function (parent, db, args, certificates) {
|
||||
socket.addListener("close", function () {
|
||||
obj.stats.onclose++;
|
||||
Debug(1, 'Swarm:Connection closed');
|
||||
if (this.relaySocket) { try { this.relaySocket.end(); delete this.relaySocket; } catch (ex) { } }
|
||||
|
||||
// Perform aggressive cleanup
|
||||
if (this.relaySocket) { try { this.relaySocket.end(); this.relaySocket.removeAllListeners(["data", "end", "error"]); delete this.relaySocket; } catch (ex) { } }
|
||||
if (this.pingTimer != null) { clearInterval(this.pingTimer); delete this.pingTimer; }
|
||||
if (this.tag && (typeof this.tag.taskid == 'number')) {
|
||||
obj.parent.taskLimiter.completed(this.tag.taskid); // Indicate this task complete
|
||||
delete this.tag.taskid;
|
||||
}
|
||||
if (this.tag) {
|
||||
if (this.tag.accumulator) { delete this.tag.accumulator; }
|
||||
if (this.tag.clientCert) { delete this.tag.clientCert; }
|
||||
delete this.tag;
|
||||
}
|
||||
this.removeAllListeners([ "data", "close", "error" ]);
|
||||
});
|
||||
|
||||
socket.addListener("error", function () {
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -795,6 +795,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id=dialog7 style="margin:auto;margin:3px">
|
||||
|
||||
<div id="d7meshkvm">
|
||||
<h4 style="width:100%;border-bottom:1px solid gray">Agent Remote Desktop</h4>
|
||||
<div style="margin:3px 0 3px 0">
|
||||
@ -839,6 +840,7 @@
|
||||
<div style="float:right;border:1px solid #666;width:200px;height:60px;overflow-y:scroll;background-color:white">
|
||||
<label><input type="checkbox" id='d7showfocus'>Show Focus Tool<br></label>
|
||||
<label><input type="checkbox" id='d7showcursor'>Show Local Mouse Cursor<br></label>
|
||||
<label><input type="checkbox" id='d7localKeyMap'>Local Keyboard Map<br></label>
|
||||
</div>
|
||||
<div>Other Settings</div>
|
||||
</div>
|
||||
@ -881,7 +883,7 @@
|
||||
var wssessions = null;
|
||||
var nodeShortIdent = 0;
|
||||
var desktop;
|
||||
var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 50 };
|
||||
var desktopsettings = { encoding: 2, showfocus: false, showmouse: true, showcad: true, quality: 40, scaling: 1024, framerate: 50, localkeymap: false };
|
||||
var multidesktopsettings = { quality: 20, scaling: 128, framerate: 1000 };
|
||||
var terminal;
|
||||
var files;
|
||||
@ -1860,7 +1862,18 @@
|
||||
}
|
||||
|
||||
function ondockeypress(e) {
|
||||
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeys(e);
|
||||
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) {
|
||||
// Check what keys we are allows to send
|
||||
if (currentNode != null) {
|
||||
var mesh = meshes[currentNode.meshid];
|
||||
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
|
||||
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
|
||||
if (inputAllowed == false) return false;
|
||||
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
|
||||
if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || (e.keyCode < 32) || (e.keyCode > 90)) return false; }
|
||||
}
|
||||
return desktop.m.handleKeys(e);
|
||||
}
|
||||
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeys(e);
|
||||
if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) return agentConsoleHandleKeys(e);
|
||||
if (!xxdialogMode && xxcurrentView == 4) {
|
||||
@ -1908,7 +1921,18 @@
|
||||
}
|
||||
|
||||
function ondockeydown(e) {
|
||||
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) { return desktop.m.handleKeyDown(e); }
|
||||
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) {
|
||||
// Check what keys we are allows to send
|
||||
if (currentNode != null) {
|
||||
var mesh = meshes[currentNode.meshid];
|
||||
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
|
||||
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
|
||||
if (inputAllowed == false) return false;
|
||||
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
|
||||
if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || (e.keyCode < 32) || (e.keyCode > 90)) return false; }
|
||||
}
|
||||
return desktop.m.handleKeyDown(e);
|
||||
}
|
||||
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) { return terminal.m.TermHandleKeyDown(e); }
|
||||
if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { haltEvent(e); return false; } // F5 Refresh on files
|
||||
if (!xxdialogMode && ((xxcurrentView == 15) || (xxcurrentView == 115))) { return agentConsoleHandleKeys(e); }
|
||||
@ -1931,7 +1955,18 @@
|
||||
}
|
||||
|
||||
function ondockeyup(e) {
|
||||
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) return desktop.m.handleKeyUp(e);
|
||||
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q("DeskControl").checked) {
|
||||
// Check what keys we are allows to send
|
||||
if (currentNode != null) {
|
||||
var mesh = meshes[currentNode.meshid];
|
||||
var meshrights = mesh.links['user/' + domain + '/' + userinfo.name.toLowerCase()].rights;
|
||||
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
|
||||
if (inputAllowed == false) return false;
|
||||
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
|
||||
if (limitedInputAllowed == true) { if ((e.altKey == true) || (e.ctrlKey == true) || (e.keyCode < 32) || (e.keyCode > 90)) return false; }
|
||||
}
|
||||
return desktop.m.handleKeyUp(e);
|
||||
}
|
||||
if (!xxdialogMode && xxcurrentView == 12 && terminal && terminal.State == 3) return terminal.m.TermHandleKeyUp(e);
|
||||
if (!xxdialogMode && xxcurrentView == 13 && e.keyCode == 116 && p13filetree != null) { p13folderup(9999); haltEvent(e); return false; } // F5 Refresh on files
|
||||
if (!xxdialogMode && xxcurrentView == 4) { if ((e.keyCode === 8 && searchFocus == 0) || e.keyCode === 27) { return haltEvent(e); } }
|
||||
@ -4080,26 +4115,27 @@
|
||||
QV('d7meshkvm', (webRtcDesktop) || ((mesh.mtype == 2) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1))));
|
||||
|
||||
// Enable buttons
|
||||
var inputAllowed = (meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) == 0));
|
||||
var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop
|
||||
QE('connectbutton1', online);
|
||||
var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal
|
||||
QE('connectbutton1h', hwonline);
|
||||
QE('deskSaveBtn', deskState == 3);
|
||||
QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (deskState != 0) && (desktopsettings.showfocus));
|
||||
QV('DeskCAD', meshrights & 8);
|
||||
QV('DeskCAD', inputAllowed);
|
||||
QE('DeskCAD', deskState == 3);
|
||||
QE('DeskClip', deskState == 3);
|
||||
QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
|
||||
QV('DeskWD', (currentNode.agent) && (currentNode.agent.id < 5) && inputAllowed);
|
||||
QE('DeskWD', deskState == 3);
|
||||
QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8));
|
||||
QV('deskkeys', (currentNode.agent) && (currentNode.agent.id < 5) && inputAllowed);
|
||||
QE('deskkeys', deskState == 3);
|
||||
|
||||
QV('DeskToolsButton', (meshrights & 8) && (mesh.mtype == 2) && online);
|
||||
QV('DeskChatButton', (browserfullscreen == false) && (meshrights & 8) && (mesh.mtype == 2) && online);
|
||||
QV('DeskNotifyButton', (browserfullscreen == false) && (currentNode.agent) && (currentNode.agent.id < 5) && (meshrights & 8) && (mesh.mtype == 2) && online);
|
||||
QV('DeskOpenWebButton', (browserfullscreen == false) && (meshrights & 8) && (mesh.mtype == 2) && online);
|
||||
QV('DeskToolsButton', (inputAllowed) && (mesh.mtype == 2) && online);
|
||||
QV('DeskChatButton', (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online);
|
||||
QV('DeskNotifyButton', (browserfullscreen == false) && (currentNode.agent) && (currentNode.agent.id < 5) && (inputAllowed) && (mesh.mtype == 2) && online);
|
||||
QV('DeskOpenWebButton', (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online);
|
||||
|
||||
QV('DeskControlSpan', meshrights & 8)
|
||||
QV('DeskControlSpan', inputAllowed)
|
||||
QV('deskActionsBtn', (browserfullscreen == false));
|
||||
QV('deskActionsSettings', (browserfullscreen == false));
|
||||
if (meshrights & 8) { Q('DeskControl').checked = (getstore('DeskControl', 1) == 1); } else { Q('DeskControl').checked = false; }
|
||||
@ -4121,6 +4157,7 @@
|
||||
desktop.onStateChanged = onDesktopStateChange;
|
||||
desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
|
||||
desktop.m.useZRLE = (desktopsettings.encoding < 3);
|
||||
desktop.m.localKeyMap = desktopsettings.localkeymap;
|
||||
desktop.m.showmouse = desktopsettings.showmouse;
|
||||
desktop.m.onScreenSizeChange = deskAdjust;
|
||||
desktop.m.onKvmData = function (x) {
|
||||
@ -4285,11 +4322,14 @@
|
||||
desktopsettings.quality = d7bitmapquality.value;
|
||||
desktopsettings.scaling = d7bitmapscaling.value;
|
||||
desktopsettings.framerate = d7framelimiter.value;
|
||||
desktopsettings.localkeymap = d7localKeyMap.checked;
|
||||
localStorage.setItem('desktopsettings', JSON.stringify(desktopsettings));
|
||||
applyDesktopSettings();
|
||||
if (desktop) {
|
||||
if (desktop.contype == 1) {
|
||||
if (desktop.State != 0) { desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate); }
|
||||
if (desktop.State != 0) {
|
||||
desktop.m.SendCompressionLevel(1, desktopsettings.quality, desktopsettings.scaling, desktopsettings.framerate);
|
||||
}
|
||||
}
|
||||
if (desktop.contype == 2) {
|
||||
if (desktopsettings.showfocus == false) { desktop.m.focusmode = 0; deskFocusBtn.value = 'All Focus'; }
|
||||
@ -4309,6 +4349,7 @@
|
||||
if (ops.indexOf(parseInt(desktopsettings.quality)) >= 0) { d7bitmapquality.value = desktopsettings.quality; }
|
||||
d7bitmapscaling.value = desktopsettings.scaling;
|
||||
if (desktopsettings.framerate) { d7framelimiter.value = desktopsettings.framerate; }
|
||||
if (desktopsettings.localkeymap) { d7localKeyMap.checked = desktopsettings.localkeymap; }
|
||||
QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (desktop.state != 0) && (desktopsettings.showfocus));
|
||||
}
|
||||
|
||||
@ -5958,6 +5999,7 @@
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20managecomputers>Manage Device Group Computers<br>';
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotecontrol>Remote Control<br>';
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remoteview style=margin-left:12px>Remote View Only<br>';
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20remotelimitedinput style=margin-left:12px>Limited Input Only<br>';
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noterminal style=margin-left:12px>No Terminal Access<br>';
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20nofiles style=margin-left:12px>No File Access<br>';
|
||||
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20noamt style=margin-left:12px>No Intel® AMT<br>';
|
||||
@ -5984,6 +6026,7 @@
|
||||
QE('p20wakedevices', !Q('p20fulladmin').checked);
|
||||
QE('p20editnotes', !Q('p20fulladmin').checked);
|
||||
QE('p20remoteview', !Q('p20fulladmin').checked && Q('p20remotecontrol').checked);
|
||||
QE('p20remotelimitedinput', !Q('p20fulladmin').checked && Q('p20remotecontrol').checked && !Q('p20remoteview').checked);
|
||||
QE('p20noterminal', !Q('p20fulladmin').checked && Q('p20remotecontrol').checked);
|
||||
QE('p20nofiles', !Q('p20fulladmin').checked && Q('p20remotecontrol').checked);
|
||||
QE('p20noamt', !Q('p20fulladmin').checked && Q('p20remotecontrol').checked);
|
||||
@ -6004,6 +6047,7 @@
|
||||
if (Q('p20noterminal').checked == true) meshadmin += 512;
|
||||
if (Q('p20nofiles').checked == true) meshadmin += 1024;
|
||||
if (Q('p20noamt').checked == true) meshadmin += 2048;
|
||||
if (Q('p20remotelimitedinput').checked == true) meshadmin += 4096;
|
||||
}
|
||||
meshserver.send({ action: 'addmeshuser', meshid: currentMesh._id, meshname: currentMesh.name, username: Q('dp20username').value , meshadmin: meshadmin});
|
||||
}
|
||||
@ -6021,10 +6065,11 @@
|
||||
if ((meshrights & 32) != 0) r += ', Server Files';
|
||||
if ((meshrights & 64) != 0) r += ', Wake Devices';
|
||||
if ((meshrights & 128) != 0) r += ', Edit Notes';
|
||||
if ((meshrights & 256) != 0) r += ', Remote View Only';
|
||||
if ((meshrights & 512) != 0) r += ', No Terminal';
|
||||
if ((meshrights & 1024) != 0) r += ', No Files';
|
||||
if ((meshrights & 2048) != 0) r += ', No Intel® AMT';
|
||||
if (((meshrights & 8) != 0) && (meshrights & 256) != 0) r += ', Remote View Only';
|
||||
if (((meshrights & 8) != 0) && (meshrights & 512) != 0) r += ', No Terminal';
|
||||
if (((meshrights & 8) != 0) && (meshrights & 1024) != 0) r += ', No Files';
|
||||
if (((meshrights & 8) != 0) && (meshrights & 2048) != 0) r += ', No Intel® AMT';
|
||||
if (((meshrights & 8) != 0) && ((meshrights & 4096) != 0) && ((meshrights & 256) == 0)) r += ', Limited Input';
|
||||
}
|
||||
r = r.substring(2);
|
||||
if (r == '') { r = 'No Rights'; }
|
||||
|
Loading…
Reference in New Issue
Block a user