mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-24 22:25:52 -05:00
Added device sharing link revocation.
This commit is contained in:
parent
8f76a97329
commit
248909d056
@ -2590,7 +2590,7 @@ function createMeshCore(agent) {
|
||||
var response = null;
|
||||
switch (cmd) {
|
||||
case 'help': { // Displays available commands
|
||||
var fin = '', f = '', availcommands = 'coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,sendcaps,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg';
|
||||
var fin = '', f = '', availcommands = 'coreinfo, coredump,service,fdsnapshot,fdcount,startupoptions,alert,agentsize,versions,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,sendcaps,openurl,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,wallpaper,agentmsg';
|
||||
if (process.platform == 'win32') { availcommands += ',safemode,wpfhwacceleration,uac'; }
|
||||
if (amt != null) { availcommands += ',amt,amtconfig,amtevents'; }
|
||||
if (process.platform != 'freebsd') { availcommands += ',vm';}
|
||||
@ -2606,6 +2606,10 @@ function createMeshCore(agent) {
|
||||
response = "Available commands: \r\n" + fin + ".";
|
||||
break;
|
||||
}
|
||||
case 'coreinfo': {
|
||||
response = JSON.stringify(meshCoreObj, null, 2);
|
||||
break;
|
||||
}
|
||||
case 'agentmsg': {
|
||||
if (args['_'].length == 0) {
|
||||
response = "Proper usage:\r\n agentmsg add \"[message]\" [iconIndex]\r\n agentmsg remove [index]\r\n agentmsg list"; // Display usage
|
||||
|
@ -432,11 +432,11 @@ module.exports.CreateAmtManager = function (parent) {
|
||||
// Connect now
|
||||
var comm;
|
||||
if (dev.tlsfail !== true) {
|
||||
parent.debug('amt', 'Relay-Connect', "TLS", dev.name, user, pass);
|
||||
parent.debug('amt', (dev.connType == 1) ? 'Relay-Connect' : 'LMS-Connect', "TLS", dev.name, user, pass);
|
||||
comm = CreateWsmanComm(dev.nodeid, 16993, user, pass, 1, null, ciraconn); // Perform TLS
|
||||
comm.xtlsFingerprint = 0; // Perform no certificate checking
|
||||
} else {
|
||||
parent.debug('amt', 'Relay-Connect', "NoTLS", dev.name, user, pass);
|
||||
parent.debug('amt', (dev.connType == 1) ? 'Relay-Connect' : 'LMS-Connect', "NoTLS", dev.name, user, pass);
|
||||
comm = CreateWsmanComm(dev.nodeid, 16992, user, pass, 0, null, ciraconn); // No TLS
|
||||
}
|
||||
var wsstack = WsmanStackCreateService(comm);
|
||||
@ -608,7 +608,7 @@ module.exports.CreateAmtManager = function (parent) {
|
||||
if ((typeof dev.aquired.user == 'string') && (dev.aquired.user != device.intelamt.user)) { change = 1; log = 1; device.intelamt.user = dev.aquired.user; changes.push('AMT user'); }
|
||||
if ((typeof dev.aquired.pass == 'string') && (dev.aquired.pass != device.intelamt.pass)) { change = 1; log = 1; device.intelamt.pass = dev.aquired.pass; changes.push('AMT pass'); }
|
||||
if ((typeof dev.aquired.mpspass == 'string') && (dev.aquired.mpspass != device.intelamt.mpspass)) { change = 1; log = 1; device.intelamt.mpspass = dev.aquired.mpspass; changes.push('AMT MPS pass'); }
|
||||
if ((typeof dev.aquired.host == 'string') && (dev.aquired.host != device.host)) { change = 1; log = 1; device.host = dev.aquired.host; changes.push('host'); }
|
||||
if ((typeof dev.aquired.host == 'string') && (dev.aquired.host != device.intelamt.host)) { change = 1; log = 1; device.intelamt.host = dev.aquired.host; changes.push('AMT host'); }
|
||||
if ((typeof dev.aquired.realm == 'string') && (dev.aquired.realm != device.intelamt.realm)) { change = 1; log = 1; device.intelamt.realm = dev.aquired.realm; changes.push('AMT realm'); }
|
||||
if ((typeof dev.aquired.hash == 'string') && (dev.aquired.hash != device.intelamt.hash)) { change = 1; log = 1; device.intelamt.hash = dev.aquired.hash; changes.push('AMT hash'); }
|
||||
if ((typeof dev.aquired.tls == 'number') && (dev.aquired.tls != device.intelamt.tls)) { change = 1; log = 1; device.intelamt.tls = dev.aquired.tls; changes.push('AMT TLS'); }
|
||||
|
17
db.js
17
db.js
@ -851,6 +851,13 @@ module.exports.CreateDB = function (parent, func) {
|
||||
}
|
||||
}
|
||||
};
|
||||
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
||||
if (id && (id != '')) {
|
||||
sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id = ? AND type = ? AND domain = ? AND nodeid IN (?)', [id, type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); });
|
||||
} else {
|
||||
sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ? AND domain = ? AND nodeid IN (?)', [type, domain, nodes], function (err, docs) { if (err == null) { for (var i in docs) { delete docs[i].type } } func(err, docs); });
|
||||
}
|
||||
};
|
||||
obj.GetAllType = function (type, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE type = ?', [type], func); }
|
||||
obj.GetAllIdsOfType = function (ids, domain, type, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE id IN (?) AND domain = ? AND type = ?', [ids, domain, type], func); }
|
||||
obj.GetUserWithEmail = function (domain, email, func) { sqlDbQuery('SELECT doc FROM meshcentral.main WHERE domain = ? AND extra = ?', [domain, 'email/' + email], func); }
|
||||
@ -1010,6 +1017,11 @@ module.exports.CreateDB = function (parent, func) {
|
||||
obj.file.find(x, { type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||
}
|
||||
};
|
||||
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
||||
var x = { type: type, domain: domain, nodeid: { $in: nodes } };
|
||||
if (id) { x._id = id; }
|
||||
obj.file.find(x, { type: 0 }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||
};
|
||||
obj.GetAllType = function (type, func) { obj.file.find({ type: type }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }).toArray(function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||
@ -1163,6 +1175,11 @@ module.exports.CreateDB = function (parent, func) {
|
||||
obj.file.find(x, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||
}
|
||||
};
|
||||
obj.GetAllTypeNodeFiltered = function (nodes, domain, type, id, func) {
|
||||
var x = { type: type, domain: domain, nodeid: { $in: nodes } };
|
||||
if (id) { x._id = id; }
|
||||
obj.file.find(x, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); });
|
||||
};
|
||||
obj.GetAllType = function (type, func) { obj.file.find({ type: type }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||
obj.GetAllIdsOfType = function (ids, domain, type, func) { obj.file.find({ type: type, domain: domain, _id: { $in: ids } }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||
obj.GetUserWithEmail = function (domain, email, func) { obj.file.find({ type: 'user', domain: domain, email: email }, { type: 0 }, function (err, docs) { func(err, performTypedRecordDecrypt(docs)); }); };
|
||||
|
33
meshagent.js
33
meshagent.js
@ -1135,6 +1135,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
case 'coreinfo':
|
||||
{
|
||||
// Sent by the agent to update agent information
|
||||
// TODO: Check that this does not include outdates Intel AMT information
|
||||
ChangeAgentCoreInfo(command);
|
||||
break;
|
||||
}
|
||||
@ -1255,34 +1256,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'acmactivate':
|
||||
{
|
||||
if (obj.agentInfo.capabilities & 0x20) return; // If this is a temporary device, don't do ACM activation.
|
||||
|
||||
// Get the current Intel AMT policy
|
||||
var mesh = parent.meshes[obj.dbMeshKey];
|
||||
if ((mesh == null) || (mesh.amt == null) || (mesh.amt.type != 3) || (domain.amtacmactivation == null) || (domain.amtacmactivation.acmmatch == null) || (mesh.amt.password == null)) break; // If this is not the right policy, ignore this.
|
||||
|
||||
// Get the Intel AMT admin password, randomize if needed.
|
||||
var amtpassword = ((mesh.amt.password == '') ? getRandomAmtPassword() : mesh.amt.password);
|
||||
if (checkAmtPassword(amtpassword) == false) return; // Invalid Intel AMT password, this should never happen.
|
||||
|
||||
// Agent is asking the server to sign an Intel AMT ACM activation request
|
||||
var signResponse = parent.parent.certificateOperations.signAcmRequest(domain, command, 'admin', amtpassword, obj.remoteaddrport, obj.dbNodeKey, obj.dbMeshKey, obj.agentInfo.computerName, obj.agentInfo.agentId); // TODO: Place account credentials!!!
|
||||
if ((signResponse != null) && (signResponse.error == null)) {
|
||||
// Log this activation event
|
||||
var event = { etype: 'node', action: 'amtactivate', nodeid: obj.dbNodeKey, domain: domain.id, msgid: 58, msgArgs: [command.fqdn], msg: 'Device requested Intel(R) AMT ACM activation, FQDN: ' + command.fqdn, ip: obj.remoteaddrport };
|
||||
if (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(obj.dbMeshKey, [obj.dbNodeKey]), obj, event);
|
||||
|
||||
// Update the device Intel AMT information
|
||||
ChangeAgentCoreInfo({ 'intelamt': { user: 'admin', pass: amtpassword, uuid: command.uuid, realm: command.realm } });
|
||||
|
||||
// Send the activation response
|
||||
obj.send(JSON.stringify(signResponse));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'diagnostic':
|
||||
{
|
||||
if (typeof command.value == 'object') {
|
||||
@ -1482,13 +1455,13 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
if (!device.intelamt) { device.intelamt = {}; }
|
||||
if ((command.intelamt.ver != null) && (typeof command.intelamt.ver == 'string') && (command.intelamt.ver.length < 12) && (device.intelamt.ver != command.intelamt.ver)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.ver; change = 1; log = 1; }
|
||||
if ((command.intelamt.sku != null) && (typeof command.intelamt.sku == 'number') && (device.intelamt.sku !== command.intelamt.sku)) { changes.push('AMT SKU'); device.intelamt.sku = command.intelamt.sku; change = 1; log = 1; }
|
||||
if ((command.intelamt.state != null) && (typeof command.intelamt.state == 'number') && (device.intelamt.state != command.intelamt.state)) { changes.push('AMT state'); device.intelamt.state = command.intelamt.state; change = 1; log = 1; }
|
||||
if ((command.intelamt.state != null) && (typeof command.intelamt.state == 'number') && (device.intelamt.state != command.intelamt.state)) { changes.push('AMT state'); console.log('agent', device.intelamt.state, command.intelamt.state); device.intelamt.state = command.intelamt.state; change = 1; log = 1; }
|
||||
if ((command.intelamt.flags != null) && (typeof command.intelamt.flags == 'number') && (device.intelamt.flags != command.intelamt.flags)) {
|
||||
if (device.intelamt.flags) { changes.push('AMT flags (' + device.intelamt.flags + ' --> ' + command.intelamt.flags + ')'); } else { changes.push('AMT flags (' + command.intelamt.flags + ')'); }
|
||||
device.intelamt.flags = command.intelamt.flags; change = 1; log = 1;
|
||||
}
|
||||
if ((command.intelamt.realm != null) && (typeof command.intelamt.realm == 'string') && (device.intelamt.realm != command.intelamt.realm)) { changes.push('AMT realm'); device.intelamt.realm = command.intelamt.realm; change = 1; log = 1; }
|
||||
if ((command.intelamt.host != null) && (typeof command.intelamt.host == 'string') && (device.intelamt.host != command.intelamt.host)) { changes.push('AMT host'); device.intelamt.host = command.intelamt.host; change = 1; log = 1; }
|
||||
//if ((command.intelamt.host != null) && (typeof command.intelamt.host == 'string') && (device.intelamt.host != command.intelamt.host)) { changes.push('AMT host'); device.intelamt.host = command.intelamt.host; change = 1; log = 1; }
|
||||
if ((command.intelamt.uuid != null) && (typeof command.intelamt.uuid == 'string') && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; log = 1; }
|
||||
if ((command.intelamt.user != null) && (typeof command.intelamt.user == 'string') && (device.intelamt.user != command.intelamt.user)) { changes.push('AMT user'); device.intelamt.user = command.intelamt.user; change = 1; log = 1; }
|
||||
if ((command.intelamt.pass != null) && (typeof command.intelamt.pass == 'string') && (device.intelamt.pass != command.intelamt.pass)) { changes.push('AMT pass'); device.intelamt.pass = command.intelamt.pass; change = 1; log = 1; }
|
||||
|
@ -803,7 +803,32 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
function checkDeviceSharePublicIdentifier(parent, domain, nodeid, pid, func) {
|
||||
// Check the public id
|
||||
parent.db.GetAllTypeNodeFiltered([nodeid], domain.id, 'deviceshare', null, function (err, docs) {
|
||||
if ((err != null) || (docs.length == 0)) { func(false); return; }
|
||||
|
||||
// Search for the device share public identifier
|
||||
var found = false;
|
||||
for (var i = 0; i < docs.length; i++) { if (docs[i].publicid == pid) { found = true; } }
|
||||
func(found);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie) {
|
||||
if ((cookie != null) && (typeof cookie.nid == 'string') && (typeof cookie.pid == 'string')) {
|
||||
checkDeviceSharePublicIdentifier(parent, domain, cookie.nid, cookie.pid, function (result) {
|
||||
// If the identifier if not found, close the connection
|
||||
if (result == false) { try { ws.close(); } catch (e) { } return; }
|
||||
// Public device sharing identifier found, continue as normal.
|
||||
CreateMeshRelayEx(parent, ws, req, domain, user, cookie);
|
||||
});
|
||||
} else {
|
||||
CreateMeshRelayEx(parent, ws, req, domain, user, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
|
||||
const currentTime = Date.now();
|
||||
if (cookie) {
|
||||
if ((typeof cookie.expire == 'number') && (cookie.expire <= currentTime)) { delete req.query.nodeid; }
|
||||
@ -819,6 +844,14 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||
obj.ruserid = null;
|
||||
obj.req = req; // Used in multi-server.js
|
||||
|
||||
// Setup subscription for desktop sharing public identifier
|
||||
// If the identifier is removed, drop the connection
|
||||
if ((cookie != null) && (typeof cookie.pid == 'string')) {
|
||||
obj.pid = cookie.pid;
|
||||
parent.parent.AddEventDispatch([obj.nodeid], obj);
|
||||
obj.HandleEvent = function (source, event, ids, id) { if ((event.action == 'removedDeviceShare') && (obj.pid == event.publicid)) { obj.close(); } }
|
||||
}
|
||||
|
||||
// Check relay authentication
|
||||
if ((user == null) && (obj.req.query != null) && (obj.req.query.rauth != null)) {
|
||||
const rcookie = parent.parent.decodeCookie(obj.req.query.rauth, parent.parent.loginCookieEncryptionKey, 240); // Cookie with 4 hour timeout
|
||||
@ -878,6 +911,9 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||
// Clear timers if present
|
||||
if (obj.pingtimer != null) { clearInterval(obj.pingtimer); delete obj.pingtimer; }
|
||||
if (obj.pongtimer != null) { clearInterval(obj.pongtimer); delete obj.pongtimer; }
|
||||
|
||||
// Unsubscribe
|
||||
if (obj.pid != null) { parent.parent.RemoveAllEventDispatch(obj); }
|
||||
};
|
||||
|
||||
obj.sendAgentMessage = function (command, userid, domainid) {
|
||||
|
40
meshrelay.js
40
meshrelay.js
@ -13,7 +13,33 @@
|
||||
/*jshint esversion: 6 */
|
||||
"use strict";
|
||||
|
||||
|
||||
function checkDeviceSharePublicIdentifier(parent, domain, nodeid, pid, func) {
|
||||
// Check the public id
|
||||
parent.db.GetAllTypeNodeFiltered([nodeid], domain.id, 'deviceshare', null, function (err, docs) {
|
||||
if ((err != null) || (docs.length == 0)) { func(false); return; }
|
||||
|
||||
// Search for the device share public identifier
|
||||
var found = false;
|
||||
for (var i = 0; i < docs.length; i++) { if (docs[i].publicid == pid) { found = true; } }
|
||||
func(found);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie) {
|
||||
if ((cookie != null) && (typeof cookie.nid == 'string') && (typeof cookie.pid == 'string')) {
|
||||
checkDeviceSharePublicIdentifier(parent, domain, cookie.nid, cookie.pid, function (result) {
|
||||
// If the identifier if not found, close the connection
|
||||
if (result == false) { try { ws.close(); } catch (e) { } return; }
|
||||
// Public device sharing identifier found, continue as normal.
|
||||
CreateMeshRelayEx(parent, ws, req, domain, user, cookie);
|
||||
});
|
||||
} else {
|
||||
CreateMeshRelayEx(parent, ws, req, domain, user, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
function CreateMeshRelayEx(parent, ws, req, domain, user, cookie) {
|
||||
const currentTime = Date.now();
|
||||
if (cookie) {
|
||||
if ((typeof cookie.expire == 'number') && (cookie.expire <= currentTime)) { try { ws.close(); parent.parent.debug('relay', 'Relay: Expires cookie (' + req.clientIp + ')'); } catch (e) { console.log(e); } return; }
|
||||
@ -26,6 +52,14 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||
obj.ruserid = null;
|
||||
obj.req = req; // Used in multi-server.js
|
||||
|
||||
// Setup subscription for desktop sharing public identifier
|
||||
// If the identifier is removed, drop the connection
|
||||
if ((cookie != null) && (typeof cookie.pid == 'string')) {
|
||||
obj.pid = cookie.pid;
|
||||
parent.parent.AddEventDispatch([cookie.nid], obj);
|
||||
obj.HandleEvent = function (source, event, ids, id) { if ((event.action == 'removedDeviceShare') && (obj.pid == event.publicid)) { closeBothSides(); } }
|
||||
}
|
||||
|
||||
// Check relay authentication
|
||||
if ((user == null) && (obj.req.query != null) && (obj.req.query.rauth != null)) {
|
||||
const rcookie = parent.parent.decodeCookie(obj.req.query.rauth, parent.parent.loginCookieEncryptionKey, 240); // Cookie with 4 hour timeout
|
||||
@ -78,6 +112,9 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||
delete obj.ws;
|
||||
delete obj.peer;
|
||||
delete obj.expireTimer;
|
||||
|
||||
// Unsubscribe
|
||||
if (obj.pid != null) { parent.parent.RemoveAllEventDispatch(obj); }
|
||||
};
|
||||
|
||||
obj.sendAgentMessage = function (command, userid, domainid) {
|
||||
@ -465,6 +502,9 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
|
||||
delete obj.peer;
|
||||
if (obj.pingtimer != null) { clearInterval(obj.pingtimer); delete obj.pingtimer; }
|
||||
if (obj.pongtimer != null) { clearInterval(obj.pongtimer); delete obj.pongtimer; }
|
||||
|
||||
// Unsubscribe
|
||||
if (obj.pid != null) { parent.parent.RemoveAllEventDispatch(obj); }
|
||||
}
|
||||
|
||||
// Record a new entry in a recording log
|
||||
|
134
meshuser.js
134
meshuser.js
@ -4577,9 +4577,107 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
ws.send(JSON.stringify({ action: 'createInviteLink', meshid: command.meshid, url: url, expire: command.expire, cookie: inviteCookie, responseid: command.responseid, tag: command.tag }));
|
||||
break;
|
||||
}
|
||||
case 'deviceShares': {
|
||||
var err = null;
|
||||
if (common.validateString(command.nodeid, 8, 128) == false) { err = 'Invalid node id'; } // Check the nodeid
|
||||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'deviceShares', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the device rights
|
||||
parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
|
||||
// If node not found or we don't have remote control, reject.
|
||||
if ((node == null) || ((rights & 8) == 0)) return;
|
||||
|
||||
// If there is MESHRIGHT_DESKLIMITEDINPUT or MESHRIGHT_REMOTEVIEWONLY on this account, reject this request.
|
||||
if ((rights != 0xFFFFFFFF) && ((rights & 4352) != 0)) return;
|
||||
|
||||
parent.db.GetAllTypeNodeFiltered([command.nodeid], domain.id, 'deviceshare', null, function (err, docs) {
|
||||
if (err != null) return;
|
||||
var now = Date.now(), removed = false, okDocs = [];
|
||||
for (var i = 0; i < docs.length; i++) {
|
||||
const doc = docs[i];
|
||||
if (doc.expireTime < now) {
|
||||
// This share is expired.
|
||||
parent.db.Remove(doc._id, function () { }); delete docs[i]; removed = true;
|
||||
} else {
|
||||
// This share is ok, remove extra data we don't need to send.
|
||||
delete doc._id; delete doc.domain; delete doc.nodeid; delete doc.type;
|
||||
okDocs.push(doc);
|
||||
}
|
||||
}
|
||||
try { ws.send(JSON.stringify({ action: 'deviceShares', nodeid: command.nodeid, deviceShares: okDocs })); } catch (ex) { }
|
||||
|
||||
// If we removed any shares, send device share update
|
||||
if (removed == true) {
|
||||
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'node', nodeid: node._id, action: 'deviceShareUpdate', domain: domain.id, deviceShares: okDocs, nolog: 1 });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case 'removeDeviceShare': {
|
||||
var err = null;
|
||||
if (common.validateString(command.nodeid, 8, 128) == false) { err = 'Invalid node id'; } // Check the nodeid
|
||||
else if (common.validateString(command.publicid, 1, 128) == false) { err = 'Invalid public id'; } // Check the public identifier
|
||||
|
||||
// Handle any errors
|
||||
if (err != null) {
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removeDeviceShare', responseid: command.responseid, result: err })); } catch (ex) { } }
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the device rights
|
||||
parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
|
||||
// If node not found or we don't have remote control, reject.
|
||||
if ((node == null) || ((rights & 8) == 0)) return;
|
||||
|
||||
// If there is MESHRIGHT_DESKLIMITEDINPUT or MESHRIGHT_REMOTEVIEWONLY on this account, reject this request.
|
||||
if ((rights != 0xFFFFFFFF) && ((rights & 4352) != 0)) return;
|
||||
|
||||
parent.db.GetAllTypeNodeFiltered([command.nodeid], domain.id, 'deviceshare', null, function (err, docs) {
|
||||
if (err != null) return;
|
||||
|
||||
// Remove device sharing
|
||||
var now = Date.now(), removedExact = null, removed = false, okDocs = [];
|
||||
for (var i = 0; i < docs.length; i++) {
|
||||
const doc = docs[i];
|
||||
if (doc.publicid == command.publicid) { parent.db.Remove(doc._id, function () { }); removedExact = doc; removed = true; }
|
||||
else if (doc.expireTime < now) { parent.db.Remove(doc._id, function () { }); removed = true; } else {
|
||||
// This share is ok, remove extra data we don't need to send.
|
||||
delete doc._id; delete doc.domain; delete doc.nodeid; delete doc.type;
|
||||
okDocs.push(doc);
|
||||
}
|
||||
}
|
||||
|
||||
// Confirm removal if requested
|
||||
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'removeDeviceShare', responseid: command.responseid, nodeid: command.nodeid, publicid: doc.publicid, removed: removedExact })); } catch (ex) { } }
|
||||
|
||||
// Event device share removal
|
||||
if (removedExact != null) {
|
||||
// Send out an event that we removed a device share
|
||||
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
|
||||
var event = { etype: 'node', userid: user._id, username: user.name, nodeid: node._id, action: 'removedDeviceShare', msg: 'Removed Device Share', msgid: 102, msgArgs: [removedExact.guestName], domain: domain.id, publicid: command.publicid };
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
}
|
||||
|
||||
// If we removed any shares, send device share update
|
||||
if (removed == true) {
|
||||
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'node', nodeid: node._id, action: 'deviceShareUpdate', domain: domain.id, deviceShares: okDocs, nolog: 1 });
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'createDeviceShareLink': {
|
||||
var err = null, maxExpireMinutes = (typeof domain.maxguestsessionsharingtime == 'number') ? domain.maxguestsessionsharingtime : 60;
|
||||
if (common.validateString(command.nodeid, 8, 128) == false) { err = 'Invalid node id'; } // Check the meshid
|
||||
if (common.validateString(command.nodeid, 8, 128) == false) { err = 'Invalid node id'; } // Check the nodeid
|
||||
else if (common.validateString(command.guestname, 1, 128) == false) { err = 'Invalid guest name'; } // Check the guest name
|
||||
else if (common.validateInt(command.expire, 1, maxExpireMinutes) == false) { err = 'Invalid expire time'; } // Check the expire time in hours
|
||||
else if (common.validateInt(command.consent, 0, 256) == false) { err = 'Invalid flags'; } // Check the flags
|
||||
@ -4595,7 +4693,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the device from the database
|
||||
// Get the device rights
|
||||
parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
|
||||
// If node not found or we don't have remote control, reject.
|
||||
if ((node == null) || ((rights & 8) == 0)) return;
|
||||
@ -4604,8 +4702,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if ((rights != 0xFFFFFFFF) && ((rights & 4352) != 0)) return;
|
||||
|
||||
// Create cookie
|
||||
var expireTime = Date.now() + (60000 * command.expire);
|
||||
const inviteCookie = parent.parent.encodeCookie({ a: 5, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, expire: expireTime }, parent.parent.invitationLinkEncryptionKey);
|
||||
var publicid = getRandomPassword();
|
||||
var startTime = Date.now(), expireTime = Date.now() + (60000 * command.expire);
|
||||
const inviteCookie = parent.parent.encodeCookie({ a: 5, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, start: startTime, expire: expireTime, pid: publicid }, parent.parent.invitationLinkEncryptionKey);
|
||||
if (inviteCookie == null) { if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'createDeviceShareLink', responseid: command.responseid, result: 'Unable to generate shareing cookie' })); } catch (ex) { } } return; }
|
||||
command.expire = expireTime;
|
||||
|
||||
@ -4618,6 +4717,33 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
if (serverName.split('.') == 1) { url = '/' + xdomain + 'desktop?c=' + inviteCookie; }
|
||||
command.url = url;
|
||||
ws.send(JSON.stringify(command));
|
||||
|
||||
// Create a device sharing database entry
|
||||
parent.db.Set({ type: 'deviceshare', nodeid: node._id, domain: node.domain, publicid: publicid, startTime: startTime, expireTime: expireTime, userid: user._id, guestName: command.guestname, consent: command.consent, url: url });
|
||||
|
||||
// Send out an event that we added a device share
|
||||
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
|
||||
var event = { etype: 'node', userid: user._id, username: user.name, nodeid: node._id, action: 'addedDeviceShare', msg: 'Added Device Share', msgid: 101, msgArgs: [command.guestname, 'DATETIME:' + startTime, 'DATETIME:' + expireTime], domain: domain.id };
|
||||
parent.parent.DispatchEvent(targets, obj, event);
|
||||
|
||||
// Send device share update
|
||||
parent.db.GetAllTypeNodeFiltered([command.nodeid], domain.id, 'deviceshare', null, function (err, docs) {
|
||||
if (err != null) return;
|
||||
|
||||
// Check device sharing
|
||||
var now = Date.now();
|
||||
for (var i = 0; i < docs.length; i++) {
|
||||
const doc = docs[i];
|
||||
if (doc.expireTime < now) { parent.db.Remove(doc._id, function () { }); delete docs[i]; } else {
|
||||
// This share is ok, remove extra data we don't need to send.
|
||||
delete doc._id; delete doc.domain; delete doc.nodeid; delete doc.type;
|
||||
}
|
||||
}
|
||||
|
||||
// Send device share update
|
||||
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
|
||||
parent.parent.DispatchEvent(targets, obj, { etype: 'node', nodeid: node._id, action: 'deviceShareUpdate', domain: domain.id, deviceShares: docs, nolog: 1 });
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
39
mpsserver.js
39
mpsserver.js
@ -701,7 +701,6 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
||||
var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen);
|
||||
var port = common.ReadInt(data, 10 + requestLen + addrLen);
|
||||
parent.debug('mpscmd', '--> GLOBAL_REQUEST', request, addr + ':' + port);
|
||||
ChangeHostname(socket, addr, socket.tag.SystemId);
|
||||
if (socket.tag.boundPorts.indexOf(port) == -1) { socket.tag.boundPorts.push(port); }
|
||||
SendTcpForwardSuccessReply(socket, port);
|
||||
return 14 + requestLen + addrLen;
|
||||
@ -1131,44 +1130,6 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
||||
return cirachannel;
|
||||
};
|
||||
|
||||
function ChangeHostname(socket, host, systemid) {
|
||||
if (socket.tag.host === host) return; // Nothing to change
|
||||
socket.tag.host = host;
|
||||
|
||||
// Change the device
|
||||
obj.db.Get(socket.tag.nodeid, function (err, nodes) {
|
||||
if ((nodes == null) || (nodes.length !== 1)) return;
|
||||
var node = nodes[0];
|
||||
|
||||
// See if any changes need to be made
|
||||
if ((node.intelamt != null) && (node.intelamt.host == host) && (node.name != null) && (node.name != '') && (node.intelamt.state == 2)) return;
|
||||
|
||||
// Get the mesh for this device
|
||||
obj.db.Get(node.meshid, function (err, meshes) {
|
||||
if ((meshes == null) || (meshes.length !== 1)) return;
|
||||
var mesh = meshes[0];
|
||||
|
||||
// Ready the node change event
|
||||
var changes = ['host'], event = { etype: 'node', action: 'changenode', nodeid: node._id };
|
||||
event.msg = +": ";
|
||||
|
||||
// Make the change & save
|
||||
if (node.intelamt == null) node.intelamt = {};
|
||||
node.intelamt.host = host;
|
||||
node.intelamt.state = 2; // Set the state to activated, since this is pretty obvious, we have a CIRA connection.
|
||||
if (((node.name == null) || (node.name == '')) && (host != null) && (host != '')) { node.name = host.split('.')[0]; } // If this system has no name, set it to the start of the domain name.
|
||||
if (((node.name == null) || (node.name == '')) && (systemid != null)) { node.name = systemid; } // If this system still has no name, set it to the system GUID.
|
||||
obj.db.Set(node);
|
||||
|
||||
// Event the node change
|
||||
event.msg = 'CIRA changed device ' + node.name + ' from group ' + mesh.name + ': ' + changes.join(', ');
|
||||
event.node = parent.webserver.CloneSafeNode(node);
|
||||
if (obj.db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come.
|
||||
obj.parent.DispatchEvent(['*', node.meshid], obj, event);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Change a node to a new meshid, this is called when a node changes groups.
|
||||
obj.changeDeviceMesh = function (nodeid, newMeshId) {
|
||||
var connectionArray = obj.ciraConnections[nodeid];
|
||||
|
2
public/scripts/amt-wsman-0.2.0-min.js
vendored
2
public/scripts/amt-wsman-0.2.0-min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -1795,6 +1795,7 @@
|
||||
powerTimelineReq = null;
|
||||
powerTimelineNode = null;
|
||||
powerTimelineUpdate = null;
|
||||
deviceShares = null;
|
||||
deleteAllNotifications(); // Close and clear notifications if present
|
||||
hideContextMenu(); // Hide the context menu if present
|
||||
QV('verifyEmailId2', false);
|
||||
@ -2116,6 +2117,13 @@
|
||||
if (currentNode._id == message.nodeid) { mainUpdate(256); }
|
||||
break;
|
||||
}
|
||||
case 'deviceShares': {
|
||||
if (message.nodeid != deviceSharesReq) break;
|
||||
deviceSharesNode = message.nodeid;
|
||||
deviceShares = message.deviceShares;
|
||||
if (currentNode._id == message.nodeid) { gotoDevice(currentNode._id, xxcurrentView, true); }
|
||||
break;
|
||||
}
|
||||
case 'getsysinfo': {
|
||||
if (message.nodeid != powerTimelineReq) break;
|
||||
if (message.noinfo === true) {
|
||||
@ -2495,7 +2503,7 @@
|
||||
}
|
||||
case 'event': {
|
||||
if (!message.event.nolog) {
|
||||
if (currentNode && (message.event.nodeid == currentNode._id)) {
|
||||
if (currentNode && (message.event.nodeid == currentNode._id) && (currentDeviceEvents != null)) {
|
||||
// If this event has a nodeid and we are looking at this node, update the log in real time.
|
||||
currentDeviceEvents.unshift(message.event);
|
||||
var eventLimit = parseInt(p16limitdropdown.value);
|
||||
@ -2520,6 +2528,13 @@
|
||||
if (message.event.noact) break; // Take no action on this event
|
||||
|
||||
switch (message.event.action) {
|
||||
case 'deviceShareUpdate': {
|
||||
if (message.event.nodeid != deviceSharesReq) break;
|
||||
deviceSharesNode = message.event.nodeid;
|
||||
deviceShares = message.event.deviceShares;
|
||||
if (currentNode._id == deviceSharesNode) { gotoDevice(currentNode._id, xxcurrentView, true); }
|
||||
break;
|
||||
}
|
||||
case 'agentlog': {
|
||||
if (message.event.msgid == 98) {
|
||||
// This is a agent help request, popup a notification.
|
||||
@ -5525,6 +5540,11 @@
|
||||
var powerTimelineReq = null;
|
||||
var powerTimelineUpdate = null;
|
||||
var powerTimeline = null;
|
||||
|
||||
var deviceSharesNode = null;
|
||||
var deviceSharesReq = null;
|
||||
var deviceShares = null;
|
||||
|
||||
function getCurrentNode() { return currentNode; };
|
||||
function gotoDevice(nodeid, panel, refresh, event) {
|
||||
// Remind the user to verify the email address
|
||||
@ -5881,6 +5901,12 @@
|
||||
QH('p17info', '');
|
||||
}
|
||||
|
||||
// Request device sharing
|
||||
if ((deviceSharesNode != currentNode._id) && (deviceSharesReq != currentNode._id)) {
|
||||
deviceSharesReq = currentNode._id;
|
||||
meshserver.send({ action: 'deviceShares', nodeid: currentNode._id });
|
||||
}
|
||||
|
||||
// Reset the desktop tools
|
||||
QV('DeskTools', false);
|
||||
showDeskToolsProcesses();
|
||||
@ -5957,8 +5983,23 @@
|
||||
}
|
||||
if (count == 1) { x += '<tr><td><div style=padding:6px> <i>' + "No users with special device permissions" + '</i><div></div></div></td><td></td></tr>'; }
|
||||
x += '</tbody></table>';
|
||||
|
||||
// Show device shares
|
||||
if ((deviceShares != null) && (deviceSharesNode == currentNode._id) && (deviceShares.length > 0)) {
|
||||
x += '<br /><table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>' + "Active Device Sharing" + '</th><th scope=col style=text-align:left></th></tr>';
|
||||
count = 1;
|
||||
for (var i = 0; i < deviceShares.length; i++) {
|
||||
var dshare = deviceShares[i];
|
||||
var trash = '<a href="' + dshare.url + '" rel="noreferrer noopener" target=_blank title="' + "Device Sharing Link" + '" style=cursor:pointer><img src=images/link2.png border=0 height=10 width=10></a> <a href=# onclick=\'return p30removeDeviceSharing(event,"' + encodeURIComponentEx(currentNode._id) + '","' + encodeURIComponentEx(dshare.publicid) + '","' + encodeURIComponentEx(dshare.guestName) + '")\' title="' + "Remove device sharing" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>';
|
||||
var details = printFlexDateTime(new Date(dshare.startTime)) + ' to ' + printFlexDateTime(new Date(dshare.expireTime));
|
||||
if (dshare.consent) { if ((dshare.consent & 8) != 0) { details += ', Prompt for consent'; } }
|
||||
x += '<tr ' + (((++count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td style=width:30%><div class=m' + 2 + '></div><div> ' + dshare.guestName + '<div></div></div></td><td style=width:70%><div style=float:right>' + trash + '</div><div>' + details + '</div></td></tr>';
|
||||
}
|
||||
x += '</tbody></table>';
|
||||
}
|
||||
QH('p10html4', x);
|
||||
|
||||
|
||||
// Change the URL
|
||||
var urlviewmode = '';
|
||||
if (((features & 0x10000000) == 0) && (xxcurrentView >= 10) && (xxcurrentView <= 19) && (currentNode != null)) {
|
||||
@ -8415,7 +8456,12 @@
|
||||
msg = EscapeHtml(event.msg).split('(R)').join('®');
|
||||
} else {
|
||||
msg = eventsMessageId[event.msgid];
|
||||
if (event.msgArgs != null) { for (var i in event.msgArgs) { msg = msg.split('{' + i + '}').join(event.msgArgs[i]); } }
|
||||
for (var i in event.msgArgs) {
|
||||
var xx = event.msgArgs[i];
|
||||
if ((typeof xx == 'string') && (xx.indexOf('DATETIME:') == 0)) { xx = printFlexDateTime(new Date(parseInt(xx.substring(9)))); }
|
||||
msg = msg.split('{' + i + '}').join(xx);
|
||||
}
|
||||
//if (event.msgArgs != null) { for (var i in event.msgArgs) { msg = msg.split('{' + i + '}').join(event.msgArgs[i]); } }
|
||||
msg = EscapeHtml(msg).split('(R)').join('®');
|
||||
}
|
||||
if (event.username) {
|
||||
@ -10828,7 +10874,9 @@
|
||||
97: "Removed phone number of user {0}",
|
||||
98: "Help Requested, user: {0}, details: {1}",
|
||||
99: "Running commands as user",
|
||||
100: "Running commands as user if possible"
|
||||
100: "Running commands as user if possible",
|
||||
101: "Added device share {0} from {1} to {2}",
|
||||
102: "Removed device share {0}"
|
||||
};
|
||||
|
||||
// Highlights the device being hovered
|
||||
@ -10861,7 +10909,13 @@
|
||||
msg = EscapeHtml(event.msg).split('(R)').join('®');
|
||||
} else {
|
||||
msg = eventsMessageId[event.msgid];
|
||||
if (event.msgArgs != null) { for (var i in event.msgArgs) { msg = msg.split('{' + i + '}').join(event.msgArgs[i]); } }
|
||||
if (event.msgArgs != null) {
|
||||
for (var i in event.msgArgs) {
|
||||
var xx = event.msgArgs[i];
|
||||
if ((typeof xx == 'string') && (xx.indexOf('DATETIME:') == 0)) { xx = printFlexDateTime(new Date(parseInt(xx.substring(9)))); }
|
||||
msg = msg.split('{' + i + '}').join(xx);
|
||||
}
|
||||
}
|
||||
msg = EscapeHtml(msg).split('(R)').join('®');
|
||||
}
|
||||
if (event.nodeid) {
|
||||
@ -12357,6 +12411,11 @@
|
||||
QH('p30html2', x);
|
||||
}
|
||||
|
||||
function p30removeDeviceSharing(event, nodeid, publicid, guestname) {
|
||||
if (xxdialogMode) return;
|
||||
setDialogMode(2, "Remove Device Share", 3, function(b, tag) { meshserver.send({ action: 'removeDeviceShare', nodeid: tag[0], publicid: tag[1] }); }, format("Confirm removal of device share \"{0}\"?", decodeURIComponent(guestname)), [ decodeURIComponent(nodeid), decodeURIComponent(publicid) ]);
|
||||
}
|
||||
|
||||
function p30removeNodeFromUser(event, nodeid) {
|
||||
if (xxdialogMode) return;
|
||||
var node = getNodeFromId(decodeURIComponent(nodeid));
|
||||
@ -12441,7 +12500,12 @@
|
||||
msg = EscapeHtml(event.msg).split('(R)').join('®');
|
||||
} else {
|
||||
msg = eventsMessageId[event.msgid];
|
||||
if (event.msgArgs != null) { for (var i in event.msgArgs) { msg = msg.split('{' + i + '}').join(event.msgArgs[i]); } }
|
||||
for (var i in event.msgArgs) {
|
||||
var xx = event.msgArgs[i];
|
||||
if ((typeof xx == 'string') && (xx.indexOf('DATETIME:') == 0)) { xx = printFlexDateTime(new Date(parseInt(xx.substring(9)))); }
|
||||
msg = msg.split('{' + i + '}').join(xx);
|
||||
}
|
||||
//if (event.msgArgs != null) { for (var i in event.msgArgs) { msg = msg.split('{' + i + '}').join(event.msgArgs[i]); } }
|
||||
msg = EscapeHtml(msg).split('(R)').join('®');
|
||||
}
|
||||
if (event.nodeid) {
|
||||
@ -13700,6 +13764,7 @@
|
||||
function printDate(d) { return d.toLocaleDateString(args.locale); }
|
||||
function printTime(d) { return d.toLocaleTimeString(args.locale); }
|
||||
function printDateTime(d) { return d.toLocaleString(args.locale); }
|
||||
function printFlexDateTime(d) { if (printDate(new Date()) == printDate(d)) { return printTime(d); } else { return printDateTime(d); } }
|
||||
function addDetailItem(title, value, state) { return '<table style=width:100%><td>' + nobreak(title) + '<td style=text-align:right>' + value + '</table>'; }
|
||||
function format(format) { var args = Array.prototype.slice.call(arguments, 1); return format.replace(/{(\d+)}/g, function (match, number) { return typeof args[number] != 'undefined' ? args[number] : match; }); };
|
||||
function addTextLink(subtext, text, link) { var i = text.toLowerCase().indexOf(subtext.toLowerCase()); if (i == -1) { return text; } return text.substring(0, i) + '<a href="' + link + '">' + subtext + '</a>' + text.substring(i + subtext.length); }
|
||||
|
31
webserver.js
31
webserver.js
@ -2922,17 +2922,30 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
|
||||
// Check the inbound desktop sharing cookie
|
||||
var c = obj.parent.decodeCookie(req.query.c, obj.parent.invitationLinkEncryptionKey, 60); // 60 minute timeout
|
||||
if ((c == null) || (c.a !== 5) || (typeof c.uid != 'string') || (typeof c.nid != 'string') || (typeof c.gn != 'string') || (typeof c.cf != 'number') || (typeof c.expire != 'number') || (c.expire <= Date.now())) { res.sendStatus(404); return; }
|
||||
if ((c == null) || (c.a !== 5) || (typeof c.uid != 'string') || (typeof c.nid != 'string') || (typeof c.gn != 'string') || (typeof c.cf != 'number') || (typeof c.start != 'number') || (typeof c.expire != 'number') || (typeof c.pid != 'string') || (c.expire <= Date.now())) { res.sendStatus(404); return; }
|
||||
|
||||
// Looks good, let's create the outbound session cookies.
|
||||
// Consent flags are 1 = Notify, 8 = Prompt, 64 = Privacy Bar.
|
||||
const authCookie = obj.parent.encodeCookie({ userid: c.uid, domainid: domain.id, nid: c.nid, ip: req.clientIp, gn: c.gn, cf: 65 | c.cf, r: 8, expire: c.expire }, obj.parent.loginCookieEncryptionKey);
|
||||
// Check the start time
|
||||
if ((c.start > Date.now()) || (c.start > c.expire)) { res.sendStatus(404); return; }
|
||||
|
||||
// Lets respond by sending out the desktop viewer.
|
||||
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
|
||||
parent.debug('web', 'handleDesktopRequest: Sending guest desktop page for \"' + c.uid + '\", guest \"' + c.gn + '\".');
|
||||
res.set({ 'Cache-Control': 'no-store' });
|
||||
render(req, res, getRenderPage('desktop', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: '', domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), nodeid: c.nid, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, expire: c.expire }, req, domain));
|
||||
// Check the public id
|
||||
obj.db.GetAllTypeNodeFiltered([c.nid], domain.id, 'deviceshare', null, function (err, docs) {
|
||||
if ((err != null) || (docs.length == 0)) { res.sendStatus(404); return; }
|
||||
|
||||
// Search for the device share public identifier
|
||||
var found = false;
|
||||
for (var i = 0; i < docs.length; i++) { if (docs[i].publicid == c.pid) { found = true; } }
|
||||
if (found == false) { res.sendStatus(404); return; }
|
||||
|
||||
// Looks good, let's create the outbound session cookies.
|
||||
// Consent flags are 1 = Notify, 8 = Prompt, 64 = Privacy Bar.
|
||||
const authCookie = obj.parent.encodeCookie({ userid: c.uid, domainid: domain.id, nid: c.nid, ip: req.clientIp, gn: c.gn, cf: 65 | c.cf, r: 8, expire: c.expire, pid: c.pid }, obj.parent.loginCookieEncryptionKey);
|
||||
|
||||
// Lets respond by sending out the desktop viewer.
|
||||
var httpsPort = ((obj.args.aliasport == null) ? obj.args.port : obj.args.aliasport); // Use HTTPS alias port is specified
|
||||
parent.debug('web', 'handleDesktopRequest: Sending guest desktop page for \"' + c.uid + '\", guest \"' + c.gn + '\".');
|
||||
res.set({ 'Cache-Control': 'no-store' });
|
||||
render(req, res, getRenderPage('desktop', req, domain), getRenderArgs({ authCookie: authCookie, authRelayCookie: '', domainurl: encodeURIComponent(domain.url).replace(/'/g, '%27'), nodeid: c.nid, serverDnsName: obj.getWebServerName(domain), serverRedirPort: args.redirport, serverPublicPort: httpsPort, expire: c.expire }, req, domain));
|
||||
});
|
||||
}
|
||||
|
||||
// Handle domain redirection
|
||||
|
Loading…
Reference in New Issue
Block a user