mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-12-23 05:42:13 +03:00
Merge branch 'master' of https://github.com/Ylianst/MeshCentral into master
# Conflicts: # agents/recoverycore.js
This commit is contained in:
commit
0f9c71e1bc
@ -905,7 +905,7 @@ function createMeshCore(agent)
|
||||
switch (data.action)
|
||||
{
|
||||
case 'agentupdate':
|
||||
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash });
|
||||
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash, sessionid: data.sessionid });
|
||||
break;
|
||||
case 'msg': {
|
||||
switch (data.type)
|
||||
@ -3053,11 +3053,11 @@ function createMeshCore(agent)
|
||||
break;
|
||||
}
|
||||
case 'agentupdate':
|
||||
require('MeshAgent').SendCommand({ action: 'agentupdate' });
|
||||
require('MeshAgent').SendCommand({ action: 'agentupdate', sessionid: sessionid });
|
||||
break;
|
||||
case 'agentupdateex':
|
||||
// Perform an direct agent update without requesting any information from the server, this should not typically be used.
|
||||
agentUpdate_Start(null, { session: sessionid });
|
||||
agentUpdate_Start(null, { sessionid: sessionid });
|
||||
break;
|
||||
case 'msh':
|
||||
response = JSON.stringify(_MSH(), null, 2);
|
||||
@ -4343,7 +4343,7 @@ function createMeshCore(agent)
|
||||
function agentUpdate_Start(updateurl, updateoptions)
|
||||
{
|
||||
// If this value is null
|
||||
var sessionid = updateoptions != null ? updateoptions.session : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
||||
var sessionid = (updateoptions != null) ? updateoptions.sessionid : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
||||
|
||||
if (this._selfupdate != null)
|
||||
{
|
||||
@ -4380,7 +4380,7 @@ function createMeshCore(agent)
|
||||
return;
|
||||
}
|
||||
|
||||
sendConsoleText('Downloading update...', sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Downloading update...', sessionid); }
|
||||
var options = require('http').parseUri(updateurl != null ? updateurl : require('MeshAgent').ServerUrl);
|
||||
options.protocol = 'https:';
|
||||
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
|
||||
@ -4422,7 +4422,7 @@ function createMeshCore(agent)
|
||||
{
|
||||
if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
|
||||
{
|
||||
sendConsoleText('Download complete. HASH verified.', sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -4433,10 +4433,13 @@ function createMeshCore(agent)
|
||||
}
|
||||
else
|
||||
{
|
||||
sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid); }
|
||||
}
|
||||
|
||||
sendConsoleText('Updating and restarting agent...', sessionid);
|
||||
// Send an indication to the server that we got the update download correctly.
|
||||
try { mesh.SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
|
||||
|
||||
if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
|
||||
if (process.platform == 'win32')
|
||||
{
|
||||
// Use _wexecve() equivalent to perform the update
|
||||
@ -4458,7 +4461,7 @@ function createMeshCore(agent)
|
||||
m |= (require('fs').CHMOD_MODES.S_IXUSR | require('fs').CHMOD_MODES.S_IXGRP | require('fs').CHMOD_MODES.S_IXOTH);
|
||||
require('fs').chmodSync(process.execPath, m);
|
||||
|
||||
sendConsoleText('Restarting service...', sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
|
||||
try
|
||||
{
|
||||
// restart service
|
||||
|
@ -86,7 +86,7 @@ function windows_execve(name, agentfilename, sessionid)
|
||||
function agentUpdate_Start(updateurl, updateoptions)
|
||||
{
|
||||
// If this value is null
|
||||
var sessionid = updateoptions != null ? updateoptions.session : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
||||
var sessionid = (updateoptions != null) ? updateoptions.sessionid : null; // If this is null, messages will be broadcast. Otherwise they will be unicasted
|
||||
|
||||
if (this._selfupdate != null)
|
||||
{
|
||||
@ -123,7 +123,7 @@ function agentUpdate_Start(updateurl, updateoptions)
|
||||
return;
|
||||
}
|
||||
|
||||
sendConsoleText('Downloading update...', sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Downloading update...', sessionid); }
|
||||
var options = require('http').parseUri(updateurl != null ? updateurl : require('MeshAgent').ServerUrl);
|
||||
options.protocol = 'https:';
|
||||
if (updateurl == null) { options.path = ('/meshagents?id=' + require('MeshAgent').ARCHID); }
|
||||
@ -165,7 +165,7 @@ function agentUpdate_Start(updateurl, updateoptions)
|
||||
{
|
||||
if (updateoptions.hash.toLowerCase() == h.toString('hex').toLowerCase())
|
||||
{
|
||||
sendConsoleText('Download complete. HASH verified.', sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Download complete. HASH verified.', sessionid); }
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -179,7 +179,10 @@ function agentUpdate_Start(updateurl, updateoptions)
|
||||
sendConsoleText('Download complete. HASH=' + h.toString('hex'), sessionid);
|
||||
}
|
||||
|
||||
sendConsoleText('Updating and restarting agent...', sessionid);
|
||||
// Send an indication to the server that we got the update download correctly.
|
||||
try { mesh.SendCommand({ action: 'agentupdatedownloaded' }); } catch (e) { }
|
||||
|
||||
if (sessionid != null) { sendConsoleText('Updating and restarting agent...', sessionid); }
|
||||
if (process.platform == 'win32')
|
||||
{
|
||||
// Use _wexecve() equivalent to perform the update
|
||||
@ -199,7 +202,7 @@ function agentUpdate_Start(updateurl, updateoptions)
|
||||
// erase update
|
||||
require('fs').unlinkSync(process.cwd() + agentfilename + '.update');
|
||||
|
||||
sendConsoleText('Restarting service...', sessionid);
|
||||
if (sessionid != null) { sendConsoleText('Restarting service...', sessionid); }
|
||||
try
|
||||
{
|
||||
// restart service
|
||||
@ -404,7 +407,7 @@ require('MeshAgent').AddCommandHandler(function (data)
|
||||
switch (data.action)
|
||||
{
|
||||
case 'agentupdate':
|
||||
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash });
|
||||
agentUpdate_Start(data.url, { hash: data.hash, tlshash: data.servertlshash, sessionid: data.sessionid });
|
||||
break;
|
||||
case 'msg':
|
||||
{
|
||||
@ -660,11 +663,11 @@ function processConsoleCommand(cmd, args, rights, sessionid) {
|
||||
break;
|
||||
case 'agentupdate':
|
||||
// Request that the server send a agent update command
|
||||
require('MeshAgent').SendCommand({ action: 'agentupdate' });
|
||||
require('MeshAgent').SendCommand({ action: 'agentupdate', sessionid: sessionid });
|
||||
break;
|
||||
case 'agentupdateex':
|
||||
// Perform an direct agent update without requesting any information from the server, this should not typically be used.
|
||||
agentUpdate_Start(null, { session: sessionid });
|
||||
agentUpdate_Start(null, { sessionid: sessionid });
|
||||
break;
|
||||
case 'osinfo': { // Return the operating system information
|
||||
var i = 1;
|
||||
|
43
meshagent.js
43
meshagent.js
@ -89,7 +89,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
// Set this agent as no longer authenticated
|
||||
obj.authenticated = -1;
|
||||
|
||||
// If we where updating the agent, clean that up.
|
||||
// If we where updating the agent using native method, 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
|
||||
@ -97,6 +97,12 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
delete obj.agentUpdate;
|
||||
}
|
||||
|
||||
// If we where updating the agent meshcore method, clean that up.
|
||||
if (obj.agentCoreUpdateTaskId != null) {
|
||||
parent.parent.taskLimiter.completed(obj.agentCoreUpdateTaskId);
|
||||
delete obj.agentCoreUpdateTaskId;
|
||||
}
|
||||
|
||||
// Perform timer cleanup
|
||||
if (obj.pingtimer) { clearInterval(obj.pingtimer); delete obj.pingtimer; }
|
||||
if (obj.pongtimer) { clearInterval(obj.pongtimer); delete obj.pongtimer; }
|
||||
@ -238,7 +244,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
if (agentUpdateMethod === 2) { // Use meshcore agent update system
|
||||
// Send the recovery core to the agent, if the agent is capable of running one
|
||||
if (((obj.agentInfo.capabilities & 16) != 0) && (parent.parent.meshAgentsArchitectureNumbers[obj.agentInfo.agentId].core != null)) {
|
||||
//obj.agentCoreCheck = 1001;
|
||||
obj.agentCoreUpdate = true;
|
||||
obj.sendBinary(common.ShortToStr(11) + common.ShortToStr(0));
|
||||
}
|
||||
@ -1152,17 +1157,26 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
{
|
||||
if ((obj.agentCoreUpdate === true) && (obj.agentExeInfo != null)) {
|
||||
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
||||
parent.parent.taskLimiter.launch(function (argument, taskid, taskLimiterQueue) { // Medium priority task
|
||||
// If agent disconnection, complete and exit now.
|
||||
if (obj.authenticated != 2) { parent.parent.taskLimiter.completed(taskid); return; }
|
||||
|
||||
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
||||
obj.agentCoreUpdateTaskId = taskid;
|
||||
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
|
||||
|
||||
// Add the hash
|
||||
if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
|
||||
|
||||
// Add server TLS cert hash
|
||||
if (parent.parent.args.ignoreagenthashcheck !== true) {
|
||||
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
|
||||
if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
|
||||
}
|
||||
|
||||
// Send the agent update command
|
||||
obj.send(JSON.stringify(cmd));
|
||||
//delete obj.agentCoreUpdate;
|
||||
}, null, 1);
|
||||
} else {
|
||||
// Sent by the agent to update agent information
|
||||
ChangeAgentCoreInfo(command);
|
||||
@ -1456,17 +1470,38 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
break;
|
||||
}
|
||||
case 'agentupdate': {
|
||||
var func = function agentUpdateFunc(argument, taskid, taskLimiterQueue) { // Medium priority task
|
||||
// If agent disconnection, complete and exit now.
|
||||
if (obj.authenticated != 2) { parent.parent.taskLimiter.completed(taskid); return; }
|
||||
|
||||
// Agent is requesting an agent update
|
||||
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex };
|
||||
obj.agentCoreUpdateTaskId = taskid;
|
||||
var cmd = { action: 'agentupdate', url: obj.agentExeInfo.url, hash: obj.agentExeInfo.hashhex, sessionid: agentUpdateFunc.sessionid };
|
||||
|
||||
// Add the hash
|
||||
if (obj.agentExeInfo.fileHash != null) { cmd.hash = obj.agentExeInfo.fileHashHex; } else { cmd.hash = obj.agentExeInfo.hashhex; }
|
||||
|
||||
// Add server TLS cert hash
|
||||
if (parent.parent.args.ignoreagenthashcheck !== true) {
|
||||
const tlsCertHash = parent.webCertificateFullHashs[domain.id];
|
||||
if (tlsCertHash != null) { cmd.servertlshash = Buffer.from(tlsCertHash, 'binary').toString('hex'); }
|
||||
}
|
||||
|
||||
// Send the agent update command
|
||||
obj.send(JSON.stringify(cmd));
|
||||
}
|
||||
func.sessionid = command.sessionid;
|
||||
|
||||
// Agent update. The recovery core was loaded in the agent, send a command to update the agent
|
||||
parent.parent.taskLimiter.launch(func, null, 1);
|
||||
break;
|
||||
}
|
||||
case 'agentupdatedownloaded': {
|
||||
if (obj.agentCoreUpdateTaskId != null) {
|
||||
// Indicate this udpate task is complete
|
||||
parent.parent.taskLimiter.completed(obj.agentCoreUpdateTaskId);
|
||||
delete obj.agentCoreUpdateTaskId;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -2401,7 +2401,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
28: { id: 28, localname: 'meshagent_mips24kc', rname: 'meshagent', desc: 'Linux MIPS24KC (OpenWRT)', update: true, amt: false, platform: 'linux', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // MIPS Router with OpenWRT
|
||||
29: { id: 29, localname: 'meshagent_osx-arm-64', rname: 'meshagent', desc: 'Apple macOS ARM-64', update: true, amt: false, platform: 'osx', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // Apple Silicon ARM 64bit
|
||||
30: { id: 30, localname: 'meshagent_freebsd_x86-64', rname: 'meshagent', desc: 'FreeBSD x86-64', update: true, amt: false, platform: 'freebsd', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // FreeBSD x64
|
||||
40: { id: 28, localname: 'meshagent_mipsel24kc', rname: 'meshagent', desc: 'Linux MIPSEL24KC (OpenWRT)', update: true, amt: false, platform: 'linux', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // MIPS Router with OpenWRT
|
||||
40: { id: 40, localname: 'meshagent_mipsel24kc', rname: 'meshagent', desc: 'Linux MIPSEL24KC (OpenWRT)', update: true, amt: false, platform: 'linux', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // MIPS Router with OpenWRT
|
||||
10003: { id: 3, localname: 'MeshService.exe', rname: 'meshagent.exe', desc: 'Win x86-32 service, unsigned', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // Unsigned version of the Windows MeshAgent x86
|
||||
10004: { id: 4, localname: 'MeshService64.exe', rname: 'meshagent.exe', desc: 'Win x86-64 service, unsigned', update: true, amt: true, platform: 'win32', core: 'windows-amt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' }, // Unsigned version of the Windows MeshAgent x64
|
||||
10005: { id: 10005, localname: 'meshagent_osx-universal-64', rname: 'meshagent', desc: 'Apple macOS Universal Binary', update: true, amt: false, platform: 'osx', core: 'linux-noamt', rcore: 'linux-recovery', arcore: 'linux-agentrecovery' } // Apple Silicon + x86 universal binary
|
||||
|
@ -453,12 +453,10 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
|
||||
//console.log('ViewerData', data.length, command, cmdsize);
|
||||
switch (command) {
|
||||
case 1: // Key Events, forward to agent
|
||||
//console.log('Viewer-Keys');
|
||||
obj.sendToAgent(data);
|
||||
if (viewer.viewOnly == false) { obj.sendToAgent(data); }
|
||||
break;
|
||||
case 2: // Mouse events, forward to agent
|
||||
//console.log('Viewer-Mouse');
|
||||
obj.sendToAgent(data);
|
||||
if (viewer.viewOnly == false) { obj.sendToAgent(data); }
|
||||
break;
|
||||
case 5: // Compression
|
||||
if (data.length < 10) return;
|
||||
@ -514,15 +512,15 @@ function CreateDesktopMultiplexor(parent, domain, nodeid, func) {
|
||||
}
|
||||
break;
|
||||
case 10: // CTRL-ALT-DEL, forward to agent
|
||||
obj.sendToAgent(data);
|
||||
if (viewer.viewOnly == false) { obj.sendToAgent(data); }
|
||||
break;
|
||||
case 12: // SET DISPLAY, forward to agent
|
||||
obj.sendToAgent(data);
|
||||
if (viewer.viewOnly == false) { obj.sendToAgent(data); }
|
||||
break;
|
||||
case 14: // Touch setup
|
||||
break;
|
||||
case 85: // Unicode Key Events, forward to agent
|
||||
obj.sendToAgent(data);
|
||||
if (viewer.viewOnly == false) { obj.sendToAgent(data); }
|
||||
break;
|
||||
default:
|
||||
console.log('Un-handled viewer command: ' + command);
|
||||
@ -868,6 +866,7 @@ function CreateMeshRelayEx2(parent, ws, req, domain, user, cookie) {
|
||||
obj.user = user;
|
||||
obj.ruserid = null;
|
||||
obj.req = req; // Used in multi-server.js
|
||||
obj.viewOnly = ((cookie != null) && (cookie.vo == 1)); // set view only mode
|
||||
|
||||
// Setup subscription for desktop sharing public identifier
|
||||
// If the identifier is removed, drop the connection
|
||||
|
@ -4845,7 +4845,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
expireTime = command.end * 1000;
|
||||
}
|
||||
|
||||
const inviteCookie = parent.parent.encodeCookie({ a: 5, p: command.p, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, start: startTime, expire: expireTime, pid: publicid }, parent.parent.invitationLinkEncryptionKey);
|
||||
var cookie = { a: 5, p: command.p, uid: user._id, gn: command.guestname, nid: node._id, cf: command.consent, start: startTime, expire: expireTime, pid: publicid };
|
||||
if (command.viewOnly === true) { cookie.vo = 1; }
|
||||
const inviteCookie = parent.parent.encodeCookie(cookie, 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.start = startTime;
|
||||
command.expire = expireTime;
|
||||
@ -4863,7 +4865,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||
try { ws.send(JSON.stringify(command)); } catch (ex) { }
|
||||
|
||||
// Create a device sharing database entry
|
||||
parent.db.Set({ _id: 'deviceshare-' + publicid, type: 'deviceshare', nodeid: node._id, p: command.p, domain: node.domain, publicid: publicid, startTime: startTime, expireTime: expireTime, userid: user._id, guestName: command.guestname, consent: command.consent, url: url });
|
||||
var shareEntry = { _id: 'deviceshare-' + publicid, type: 'deviceshare', nodeid: node._id, p: command.p, domain: node.domain, publicid: publicid, startTime: startTime, expireTime: expireTime, userid: user._id, guestName: command.guestname, consent: command.consent, url: url };
|
||||
if (command.viewOnly === true) { shareEntry.viewOnly = true; }
|
||||
parent.db.Set(shareEntry);
|
||||
|
||||
// Send out an event that we added a device share
|
||||
var targets = parent.CreateNodeDispatchTargets(node.meshid, node._id, ['server-users', user._id]);
|
||||
|
BIN
public/images/details/mobile128.png
Normal file
BIN
public/images/details/mobile128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
public/images/details/mobile32.png
Normal file
BIN
public/images/details/mobile32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
BIN
public/images/details/mobile64.png
Normal file
BIN
public/images/details/mobile64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
2
public/scripts/agent-desktop-0.0.2-min.js
vendored
2
public/scripts/agent-desktop-0.0.2-min.js
vendored
File diff suppressed because one or more lines are too long
@ -266,7 +266,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
|
||||
}
|
||||
break;
|
||||
case 88: // MNG_KVM_MOUSE_CURSOR
|
||||
if (cmdsize != 5) break;
|
||||
if ((cmdsize != 5) || (obj.stopInput)) break;
|
||||
var cursorNum = view[4];
|
||||
if (cursorNum > mouseCursors.length) { cursorNum = 0; }
|
||||
xMouseCursorCurrent = mouseCursors[cursorNum];
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4326,6 +4326,17 @@
|
||||
if (x != '') { sections.push({ name: "Mesh Agent", html: x, img: 'meshagent' }); }
|
||||
}
|
||||
|
||||
// Mobile
|
||||
if (hardware.mobile) {
|
||||
var x = '';
|
||||
if (hardware.mobile.brand && hardware.mobile.model) { x += addDetailItem("Model", EscapeHtml(hardware.mobile.brand + ', ' + hardware.mobile.model), s); }
|
||||
if (hardware.mobile.device) { x += addDetailItem("Device", EscapeHtml(hardware.mobile.device), s); }
|
||||
if (hardware.mobile.bootloader) { x += addDetailItem("Bootloader", EscapeHtml(hardware.mobile.bootloader), s); }
|
||||
if (hardware.mobile.id) { x += addDetailItem("Identifier", EscapeHtml(hardware.mobile.id), s); }
|
||||
if (hardware.mobile.host) { x += addDetailItem("Hostname", EscapeHtml(hardware.mobile.host), s); }
|
||||
if (x != '') { sections.push({ name: "Mobile Device", html: x, img: 'mobile' }); }
|
||||
}
|
||||
|
||||
// Networking
|
||||
if (network.netif2 != null) {
|
||||
// Display one network interface for each MAC address
|
||||
|
@ -3148,6 +3148,7 @@
|
||||
if (node == null) break;
|
||||
x += addHtmlValue("Device", node.name);
|
||||
x += addHtmlValue("Guest Name", message.guestname);
|
||||
x += addHtmlValue("User Input", message.viewOnly ? "Not allowed, view only" : "Allowed");
|
||||
x += addHtmlValue("Start Time", printDateTime(new Date(message.start)));
|
||||
x += addHtmlValue("Expire Time", printDateTime(new Date(message.expire)));
|
||||
var y = [];
|
||||
@ -6195,6 +6196,7 @@
|
||||
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 = format("{0}, {1} to {2}", ((dshare.p == 1)?"Terminal":"Desktop"), printFlexDateTime(new Date(dshare.startTime)), printFlexDateTime(new Date(dshare.expireTime)));
|
||||
if (dshare.viewOnly === true) { details += ", View only"; }
|
||||
if (dshare.consent != null) {
|
||||
if (dshare.consent == 0) { details += ", No Consent"; } else {
|
||||
if (((dshare.consent & 8) != 0) || ((dshare.consent & 16) != 0)) { details += ", Prompt for consent"; }
|
||||
@ -6368,8 +6370,7 @@
|
||||
if (xxdialogMode) return;
|
||||
var y = '', x = "Creates a link that allows a guest without an account to remote control this device for a limited time." + '<br /><br />';
|
||||
x += addHtmlValue("Guest Name", '<input id=d2inviteName style=width:250px maxlength=128 type=text onkeyup=showShareDeviceValidate() />');
|
||||
x += addHtmlValue("Type", '<select id=d2shareType style=float:right;width:250px onchange=showShareDeviceValidate()>' + ((currentNode.agent.caps & 1)?('<option value=2>' + "Desktop" + '</option>'):'') + ((currentNode.agent.caps & 2)?('<option value=1>' + "Terminal" + '</option>'):'') + '</select>');
|
||||
|
||||
x += addHtmlValue("Type", '<select id=d2shareType style=float:right;width:250px onchange=showShareDeviceValidate()>' + ((currentNode.agent.caps & 1)?('<option value=2>' + "Desktop" + '</option><option value=3>' + "Desktop, View only" + '</option>'):'') + ((currentNode.agent.caps & 2)?('<option value=1>' + "Terminal" + '</option>'):'') + '</select>');
|
||||
var options = { 1 : "1 minute", 5 : "5 minutes", 10 : "10 minutes", 15 : "15 minutes", 30 : "30 minutes", 45 : "45 minutes", 60 : "60 minutes", 120 : "2 hours", 240 : "4 hours", 480 : "8 hours", 720 : "12 hours", 960 : "16 hours", 1440 : "24 hours", 2880 : "2 days", 5760 : "4 days" }
|
||||
for (var i in options) { y += '<option value=' + i + '>' + options[i] + '</option>'; }
|
||||
x += addHtmlValue("Validity", '<select id=d2timeRange style=float:right;width:250px onchange=showShareDeviceValidate()><option value=0>' + "Starting now" + '</option><option value=1>' + "Time range" + '</option></select>');
|
||||
@ -6391,22 +6392,21 @@
|
||||
QV('d2modenow', Q('d2timeRange').value == 0);
|
||||
QV('d2moderange', Q('d2timeRange').value == 1);
|
||||
var ok = true;
|
||||
|
||||
if (Q('d2inviteName').value.trim().length == 0) { ok = false; }
|
||||
|
||||
QE('idx_dlgOkButton', ok);
|
||||
}
|
||||
|
||||
function showShareDeviceEx(b, tag) {
|
||||
var consent = 0;
|
||||
var consent = 0, p = parseInt(Q('d2shareType').value), viewOnly = false;
|
||||
if (currentNode.agent.caps & 1) {
|
||||
if (Q('d2shareType').value == 1) { if (Q('d2userConsent').value == 1) { consent = 18; } else { consent = 2; } } // Terminal Consent: 2 = Notify, 16 = Prompt
|
||||
if (Q('d2shareType').value == 2) { if (Q('d2userConsent').value == 1) { consent = 73; } else { consent = 65; } } // Desktop Consent: 1 = Notify, 8 = Prompt, 64 = Privacy bar
|
||||
if (Q('d2shareType').value > 1) { if (Q('d2userConsent').value == 1) { consent = 73; } else { consent = 65; } } // Desktop Consent: 1 = Notify, 8 = Prompt, 64 = Privacy bar
|
||||
}
|
||||
if (p == 3) { p = 2; viewOnly = true; }
|
||||
if (Q('d2timeRange').value == 0) {
|
||||
meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: parseInt(Q('d2shareType').value), expire: parseInt(Q('d2inviteExpire').value), consent: consent });
|
||||
meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: p, expire: parseInt(Q('d2inviteExpire').value), consent: consent, viewOnly: viewOnly });
|
||||
} else {
|
||||
meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: parseInt(Q('d2shareType').value), start: Math.floor(tag.selectedDates[0].getTime() / 1000), end: Math.floor(tag.selectedDates[1].getTime() / 1000), consent: consent });
|
||||
meshserver.send({ action: 'createDeviceShareLink', nodeid: currentNode._id, guestname: Q('d2inviteName').value.trim(), p: p, start: Math.floor(tag.selectedDates[0].getTime() / 1000), end: Math.floor(tag.selectedDates[1].getTime() / 1000), consent: consent, viewOnly: viewOnly });
|
||||
}
|
||||
}
|
||||
|
||||
@ -9014,6 +9014,17 @@
|
||||
if (x != '') { sections.push({ name: "Mesh Agent", html: x, img: 'meshagent64.png'}); }
|
||||
}
|
||||
|
||||
// Mobile
|
||||
if (hardware.mobile) {
|
||||
var x = '';
|
||||
if (hardware.mobile.brand && hardware.mobile.model) { x += addDetailItem("Model", EscapeHtml(hardware.mobile.brand + ', ' + hardware.mobile.model), s); }
|
||||
if (hardware.mobile.device) { x += addDetailItem("Device", EscapeHtml(hardware.mobile.device), s); }
|
||||
if (hardware.mobile.bootloader) { x += addDetailItem("Bootloader", EscapeHtml(hardware.mobile.bootloader), s); }
|
||||
if (hardware.mobile.id) { x += addDetailItem("Identifier", EscapeHtml(hardware.mobile.id), s); }
|
||||
if (hardware.mobile.host) { x += addDetailItem("Hostname", EscapeHtml(hardware.mobile.host), s); }
|
||||
if (x != '') { sections.push({ name: "Mobile Device", html: x, img: 'mobile64.png'}); }
|
||||
}
|
||||
|
||||
// Networking (old style)
|
||||
if (network.netif != null) {
|
||||
// Compact interfaces that have the same MAC addresses
|
||||
|
@ -59,7 +59,7 @@
|
||||
<select id=termdisplays style="display:none" onchange=deskSetDisplay(event) onkeypress="return false" onkeydown="return false"></select>
|
||||
<span id=DeskSaveImageButton title="Save a screenshot of the remote desktop"><img src='images/icon-camera.png' onclick=deskSaveImage() height=16 width=16 style=padding-top:2px /></span>
|
||||
</div>
|
||||
<div>
|
||||
<div style="height:22px">
|
||||
<select id="deskkeys">
|
||||
<option value=10>Ctrl+Alt+Del</option>
|
||||
<option value=5>Win</option>
|
||||
@ -165,6 +165,7 @@
|
||||
var domain = '{{{domain}}}';
|
||||
var domainUrl = '{{{domainurl}}}';
|
||||
var authCookie = '{{{authCookie}}}';
|
||||
var viewOnly = parseInt('{{{viewOnly}}}');
|
||||
var urlargs = parseUriArgs();
|
||||
var debugmode = urlargs.debug;
|
||||
var attemptWebRTC = false;
|
||||
@ -180,8 +181,18 @@
|
||||
document.onkeydown = ondockeydown;
|
||||
document.onkeyup = ondockeyup;
|
||||
setupDesktop();
|
||||
|
||||
// View only mode
|
||||
if (viewOnly == 1) {
|
||||
QV('deskkeys', false);
|
||||
QV('DeskWD', false);
|
||||
QV('DeskClip', false);
|
||||
QV('DeskType', false);
|
||||
QV('DeskControlSpan', false);
|
||||
}
|
||||
}
|
||||
|
||||
function isInputAllowed() { return (viewOnly != 1) && (Q('DeskControl').checked == true); }
|
||||
function clearConsoleMsg() { QH('p11DeskConsoleMsg', ''); }
|
||||
|
||||
// Toggle the web page to full screen
|
||||
@ -270,21 +281,20 @@
|
||||
QV('d7amtkvm', intelAmtPresent && ((deskState == 0) || (desktop.contype == 2)));
|
||||
|
||||
// Enable buttons
|
||||
var inputAllowed = true; // TODO
|
||||
QE('connectbutton1', agentPresent);
|
||||
QE('connectbutton1h', intelAmtPresent);
|
||||
//QV('DeskClip', agentPresent && ((desktop == null) || (desktop.contype != 2))); // Clipboard not supported on macOS
|
||||
QV('DeskClip', false); // Clipboard not supported on this page
|
||||
QE('DeskClip', deskState == 3);
|
||||
QE('DeskType', deskState == 3);
|
||||
QV('DeskWD', inputAllowed);
|
||||
QV('DeskWD', viewOnly != 1);
|
||||
QE('DeskWD', deskState == 3);
|
||||
QV('deskkeys', inputAllowed);
|
||||
QV('deskkeys', viewOnly != 1);
|
||||
QE('deskkeys', deskState == 3);
|
||||
|
||||
// Display this only if we have Chat & Notify permissions
|
||||
QV('DeskSaveImageButton', (deskState == 3) && (Q('Desk')['toBlob'] != null));
|
||||
QV('DeskControlSpan', inputAllowed)
|
||||
QV('DeskControlSpan', viewOnly != 1);
|
||||
QV('deskActionsBtn', (browserfullscreen == false));
|
||||
QV('deskActionsSettings', (browserfullscreen == false));
|
||||
Q('DeskControl').checked = true;
|
||||
@ -317,6 +327,7 @@
|
||||
desktop = CreateAmtRedirect(CreateAmtRemoteDesktop('Desk'), authCookie);
|
||||
desktop.debugmode = debugmode;
|
||||
desktop.onStateChanged = onDesktopStateChange;
|
||||
desktop.m.stopInput = (viewOnly == 1);
|
||||
desktop.m.bpp = (desktopsettings.encoding == 1 || desktopsettings.encoding == 3) ? 1 : 2;
|
||||
desktop.m.useZRLE = (desktopsettings.encoding < 3);
|
||||
desktop.m.localKeyMap = desktopsettings.localkeymap;
|
||||
@ -398,6 +409,7 @@
|
||||
} else if ((contype == null) || (contype == 1) || (contype == 3)) {
|
||||
// Setup the Mesh Agent remote desktop
|
||||
desktop = CreateAgentRedirect(null, CreateAgentRemoteDesktop('Desk'), serverPublicNamePort, authCookie, null, domainUrl);
|
||||
desktop.m.stopInput = (viewOnly == 1);
|
||||
desktop.m.mouseCursorActive(true);
|
||||
desktop.debugmode = debugmode;
|
||||
desktop.m.debugmode = debugmode;
|
||||
@ -808,7 +820,7 @@
|
||||
|
||||
function ondockeypress(e) {
|
||||
setSessionActivity();
|
||||
if (!xxdialogMode && desktop && Q('DeskControl').checked) {
|
||||
if (!xxdialogMode && desktop && isInputAllowed()) {
|
||||
// Check what keys we are allows to send
|
||||
/*
|
||||
if (currentNode != null) {
|
||||
@ -825,7 +837,7 @@
|
||||
|
||||
function ondockeydown(e) {
|
||||
setSessionActivity();
|
||||
if (!xxdialogMode && desktop && Q('DeskControl').checked) {
|
||||
if (!xxdialogMode && desktop && isInputAllowed()) {
|
||||
// Check what keys we are allows to send
|
||||
/*
|
||||
if (currentNode != null) {
|
||||
@ -842,7 +854,7 @@
|
||||
|
||||
function ondockeyup(e) {
|
||||
setSessionActivity();
|
||||
if (!xxdialogMode && desktop && Q('DeskControl').checked) {
|
||||
if (!xxdialogMode && desktop && isInputAllowed()) {
|
||||
// Check what keys we are allows to send
|
||||
/*
|
||||
if (currentNode != null) {
|
||||
@ -1100,17 +1112,17 @@
|
||||
if (e.buttons != 1) return;
|
||||
var t = Date.now();
|
||||
if (((t - dblClickDetectArgs.t) < 250) && (Math.abs(e.clientX - dblClickDetectArgs.x) < 2) && (Math.abs(e.clientY - dblClickDetectArgs.y) < 2)) {
|
||||
if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedblclick(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedblclick(e); } }
|
||||
if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedblclick(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedblclick(e); } }
|
||||
}
|
||||
dblClickDetectArgs.t = t;
|
||||
dblClickDetectArgs.x = e.clientX;
|
||||
dblClickDetectArgs.y = e.clientY;
|
||||
}
|
||||
|
||||
function dmousedown(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedown(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedown(e); } } dblClickDetect(e); }
|
||||
function dmouseup(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mouseup(e); desktop.m.sendKeepAlive(); } else { desktop.m.mouseup(e); } }
|
||||
function dmousemove(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousemove(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousemove(e); } } }
|
||||
function dmousewheel(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && Q('DeskControl').checked) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousewheel(e); desktop.m.sendKeepAlive(); } else { if (desktop.m.mousewheel) { desktop.m.mousewheel(e); } } haltEvent(e); return true; } return false; }
|
||||
function dmousedown(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousedown(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousedown(e); } } dblClickDetect(e); }
|
||||
function dmouseup(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mouseup(e); desktop.m.sendKeepAlive(); } else { desktop.m.mouseup(e); } }
|
||||
function dmousemove(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousemove(e); desktop.m.sendKeepAlive(); } else { desktop.m.mousemove(e); } } }
|
||||
function dmousewheel(e) { setSessionActivity(); e.addx = Q('DeskParent').scrollLeft; e.addy = Q('DeskParent').scrollTop; if (!xxdialogMode && desktop != null && isInputAllowed()) { if ((webRtcDesktop != null) && (webRtcDesktop.softdesktop != null)) { webRtcDesktop.softdesktop.m.mousewheel(e); desktop.m.sendKeepAlive(); } else { if (desktop.m.mousewheel) { desktop.m.mousewheel(e); } } haltEvent(e); return true; } return false; }
|
||||
function drotate(x) { if (!xxdialogMode && desktop != null) { desktop.m.setRotation(desktop.m.rotation + x); deskAdjust(); deskAdjust(); } }
|
||||
function stopProcess(id, name) { setDialogMode(2, "Process Control", 3, stopProcessEx, format("Stop process #{0} \"{1}\"?", id, name), id); return false; }
|
||||
function stopProcessEx(buttons, tag) { meshserver.send({ action: 'msg', type: 'pskill', nodeid: currentNode._id, value: tag }); setTimeout(refreshDeskTools, 300); }
|
||||
|
@ -3056,13 +3056,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
||||
|
||||
// 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, p: 2, gn: c.gn, cf: 65 | c.cf, r: 8, expire: c.expire, pid: c.pid }, obj.parent.loginCookieEncryptionKey);
|
||||
const authCookie = obj.parent.encodeCookie({ userid: c.uid, domainid: domain.id, nid: c.nid, ip: req.clientIp, p: 2, gn: c.gn, cf: 65 | c.cf, r: 8, expire: c.expire, pid: c.pid, vo: c.vo }, 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));
|
||||
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, viewOnly: (c.vo == 1) ? 1 : 0 }, req, domain));
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user