Many agent & UI improvements
This commit is contained in:
parent
8dcd8938a6
commit
23bc223f18
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -29,9 +29,12 @@ function createMeshCore(agent) {
|
|||
this.Start = function Start(user) {
|
||||
if (this.container == null) {
|
||||
if (process.platform == 'win32') {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
|
||||
}
|
||||
else {
|
||||
try {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.SessionId });
|
||||
} catch (ex) {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1 });
|
||||
}
|
||||
} else {
|
||||
this.container = require('ScriptContainer').Create({ processIsolation: 1, sessionId: user.uid });
|
||||
}
|
||||
this.container.parent = this;
|
||||
|
@ -47,33 +50,21 @@ function createMeshCore(agent) {
|
|||
this._container = this.container;
|
||||
this._container.parent = this;
|
||||
this.container = null;
|
||||
|
||||
this._container.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
obj.borderManager = new borderController();
|
||||
*/
|
||||
|
||||
require('events').EventEmitter.call(obj, true).createEvent('loggedInUsers_Updated');
|
||||
obj.on('loggedInUsers_Updated', function ()
|
||||
{
|
||||
var users = []
|
||||
for(var i = 0; i < obj.loggedInUsers.length; ++i)
|
||||
{
|
||||
users.push((obj.loggedInUsers[i].Domain ? (obj.loggedInUsers[i].Domain + '\\') : '') + obj.loggedInUsers[i].Username);
|
||||
}
|
||||
sendConsoleText('LogOn Status Changed. Active Users => [' + users.join(', ') + ']');
|
||||
});
|
||||
//obj.borderManager = new borderController();
|
||||
|
||||
// MeshAgent JavaScript Core Module. This code is sent to and running on the mesh agent.
|
||||
obj.meshCoreInfo = "MeshCore v6";
|
||||
obj.meshCoreCapabilities = 14; // Capability bitmask: 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console, 16 = JavaScript
|
||||
obj.loggedInUsers = [];
|
||||
obj.loggedInUsers = null;
|
||||
|
||||
var meshServerConnectionState = 0;
|
||||
var tunnels = {};
|
||||
var lastSelfInfo = null;
|
||||
var lastMeInfo = null;
|
||||
var lastNetworkInfo = null;
|
||||
var lastPublicLocationInfo = null;
|
||||
var selfInfoUpdateTimer = null;
|
||||
|
@ -92,10 +83,8 @@ function createMeshCore(agent) {
|
|||
var nextTunnelIndex = 1;
|
||||
|
||||
// Get the operating system description string
|
||||
// *** THIS CAUSES AGENT TO BE UNSTABLE!!!
|
||||
//obj.osDesc = null;
|
||||
//try { require('os').name().then(function (v) { obj.osDesc = v; }); } catch (ex) { }
|
||||
// *** THIS CAUSES AGENT TO BE UNSTABLE!!!
|
||||
var osDesc = null;
|
||||
try { require('os').name().then(function (v) { osDesc = v; if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "coreinfo", "value": obj.meshCoreInfo, "osdesc": osDesc }); } }); } catch (ex) { }
|
||||
|
||||
/*
|
||||
var AMTScanner = require("AMTScanner");
|
||||
|
@ -128,23 +117,23 @@ function createMeshCore(agent) {
|
|||
var AMTScannerModule = require('amt-scanner');
|
||||
amtscanner = new AMTScannerModule();
|
||||
//amtscanner.on('found', function (data) { if (typeof data != 'string') { data = JSON.stringify(data, null, " "); } sendConsoleText(data); });
|
||||
} catch (e) { amtscanner = null; }
|
||||
} catch (ex) { amtscanner = null; }
|
||||
|
||||
// Try to load up the MEI module
|
||||
try {
|
||||
var amtMeiLib = require('amt-mei');
|
||||
amtMei = new amtMeiLib();
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; sendPeriodicServerUpdate(); });
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; });
|
||||
amtMeiConnected = 2;
|
||||
//amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); });
|
||||
} catch (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
|
||||
sendPeriodicServerUpdate(1);
|
||||
} catch (ex) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
|
||||
|
||||
// Try to load up the WIFI scanner
|
||||
try {
|
||||
var wifiScannerLib = require('wifi-scanner');
|
||||
wifiScanner = new wifiScannerLib();
|
||||
wifiScanner.on('accessPoint', function (data) { sendConsoleText(JSON.stringify(data)); });
|
||||
} catch (e) { wifiScannerLib = null; wifiScanner = null; }
|
||||
} catch (ex) { wifiScannerLib = null; wifiScanner = null; }
|
||||
|
||||
// If we are running in Duktape, agent will be null
|
||||
if (agent == null) {
|
||||
|
@ -923,7 +912,7 @@ function createMeshCore(agent) {
|
|||
var response = null;
|
||||
switch (cmd) {
|
||||
case 'help': { // Displays available commands
|
||||
response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendinfo, sendcaps.';
|
||||
response = 'Available commands: help, info, osinfo, args, print, type, dbget, dbset, dbcompact, eval, parseuri, httpget,\r\nwslist, wsconnect, wssend, wsclose, notify, ls, ps, kill, amt, netinfo, location, power, wakeonlan, scanwifi,\r\nscanamt, setdebug, smbios, rawsmbios, toast, lock, users, sendcaps.';
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
@ -947,12 +936,7 @@ function createMeshCore(agent) {
|
|||
*/
|
||||
case 'users':
|
||||
{
|
||||
var retList = [];
|
||||
for(var i = 0; i < obj.loggedInUsers.length; ++i)
|
||||
{
|
||||
retList.push((obj.loggedInUsers[i].Domain ? (obj.loggedInUsers[i].Domain + '\\') : '') + obj.loggedInUsers[i].Username);
|
||||
}
|
||||
response = 'Active Users => [' + retList.join(', ') + ']';
|
||||
if (obj.loggedInUsers == null) { response = 'Active users are unknown.'; } else { response = 'Active Users: ' + obj.loggedInUsers.join(', ') + '.'; }
|
||||
}
|
||||
break;
|
||||
case 'toast': {
|
||||
|
@ -1038,10 +1022,10 @@ function createMeshCore(agent) {
|
|||
case 'info': { // Return information about the agent and agent core module
|
||||
response = 'Current Core: ' + obj.meshCoreInfo + '.\r\nAgent Time: ' + Date() + '.\r\nUser Rights: 0x' + rights.toString(16) + '.\r\nPlatform: ' + process.platform + '.\r\nCapabilities: ' + obj.meshCoreCapabilities + '.\r\nServer URL: ' + mesh.ServerUrl + '.';
|
||||
if (amtLmsState >= 0) { response += '\r\nBuilt-in LMS: ' + ['Disabled', 'Connecting..', 'Connected'][amtLmsState] + '.'; }
|
||||
//if (obj.osDesc) { response += '\r\nOS: ' + obj.osDesc + '.'; }
|
||||
if (osDesc) { response += '\r\nOS: ' + osDesc + '.'; }
|
||||
response += '\r\nModules: ' + addedModules.join(', ') + '.';
|
||||
response += '\r\nServer Connection: ' + mesh.isControlChannelConnected + ', State: ' + meshServerConnectionState + '.';
|
||||
response += '\r\nLastInfo: ' + lastSelfInfo + '.';
|
||||
response += '\r\lastMeInfo: ' + lastMeInfo + '.';
|
||||
var oldNodeId = db.Get('OldNodeId');
|
||||
if (oldNodeId != null) { response += '\r\nOldNodeID: ' + oldNodeId + '.'; }
|
||||
if (process.platform != 'win32') { response += '\r\nX11 support: ' + require('monitor-info').kvm_x11_support + '.'; }
|
||||
|
@ -1049,7 +1033,7 @@ function createMeshCore(agent) {
|
|||
}
|
||||
case 'osinfo': { // Return the operating system information
|
||||
var i = 1;
|
||||
if (args['_'].length > 0) { i = parseInt(args['_'][0]); response = 'Calling ' + i + ' times.'; }
|
||||
if (args['_'].length > 0) { i = parseInt(args['_'][0]); if (i > 8) { i = 8; } response = 'Calling ' + i + ' times.'; }
|
||||
for (var j = 0; j < i; j++) {
|
||||
var pr = require('os').name();
|
||||
pr.sessionid = sessionid;
|
||||
|
@ -1057,30 +1041,24 @@ function createMeshCore(agent) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'selfinfo': { // Return self information block
|
||||
buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' ', true), sessionid); });
|
||||
break;
|
||||
}
|
||||
case 'sendinfo': { // Send our information to the server
|
||||
buildSelfInfo(function (selfInfo) {
|
||||
lastSelfInfo = JSON.stringify(selfInfo);
|
||||
sendConsoleText('Sent: ' + lastSelfInfo);
|
||||
mesh.SendCommand(lastSelfInfo);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'sendcaps': { // Send capability flags to the server
|
||||
if (args['_'].length == 0) {
|
||||
response = 'Proper usage: sendcaps (number)'; // Display correct command usage
|
||||
} else {
|
||||
var flags = 0;
|
||||
response = JSON.stringify(args);
|
||||
flags = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": parseInt(args['_'][0]) };
|
||||
var flags = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": parseInt(args['_'][0]) };
|
||||
mesh.SendCommand(flags);
|
||||
response = JSON.stringify(flags);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'sendosdesc': { // Send OS description
|
||||
var os = osDesc;
|
||||
if (args['_'].length > 0) { os = args['_'][0]; }
|
||||
var flags = { "action": "coreinfo", "value": obj.meshCoreInfo, "osdesc": os };
|
||||
mesh.SendCommand(flags);
|
||||
response = JSON.stringify(flags);
|
||||
break;
|
||||
}
|
||||
case 'args': { // Displays parsed command arguments
|
||||
response = 'args ' + objToString(args, 0, ' ', true);
|
||||
break;
|
||||
|
@ -1380,31 +1358,22 @@ function createMeshCore(agent) {
|
|||
// Server connected, send mesh core information
|
||||
var oldNodeId = db.Get('OldNodeId');
|
||||
if (oldNodeId != null) { mesh.SendCommand({ action: 'mc1migration', oldnodeid: oldNodeId }); }
|
||||
sendPeriodicServerUpdate(true);
|
||||
//if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 60000); } // Should be a long time, like 20 minutes. For now, 1 minute.
|
||||
|
||||
// Update the server wtih basic info
|
||||
var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
|
||||
if (osDesc != null) { r.osdesc = osDesc; }
|
||||
mesh.SendCommand(r);
|
||||
|
||||
// Update list of logged in users
|
||||
if (obj.loggedInUsers != null) { mesh.SendCommand({ "action": "coreinfo", "v": { "users": obj.loggedInUsers } }); }
|
||||
|
||||
// Update the server on more advanced stuff, like Intel ME and Network Settings
|
||||
meInfoStr = null;
|
||||
sendPeriodicServerUpdate();
|
||||
//if (selfInfoUpdateTimer == null) { selfInfoUpdateTimer = setInterval(sendPeriodicServerUpdate, 1200000); } // 20 minutes
|
||||
}
|
||||
}
|
||||
|
||||
// Build a bunch a self information data that will be sent to the server
|
||||
// We need to do this periodically and if anything changes, send the update to the server.
|
||||
function buildSelfInfo(func) {
|
||||
getAmtInfo(function (meinfo) {
|
||||
var r = { "action": "coreinfo", "value": obj.meshCoreInfo, "caps": obj.meshCoreCapabilities };
|
||||
try {
|
||||
if (meinfo != null) {
|
||||
var intelamt = {}, p = false;
|
||||
if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
|
||||
if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
|
||||
if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
|
||||
if (p == true) { r.intelamt = intelamt }
|
||||
}
|
||||
} catch (ex) { }
|
||||
func(r);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Update the server with the latest network interface information
|
||||
var sendNetworkUpdateNagleTimer = null;
|
||||
function sendNetworkUpdateNagle() { if (sendNetworkUpdateNagleTimer != null) { clearTimeout(sendNetworkUpdateNagleTimer); sendNetworkUpdateNagleTimer = null; } sendNetworkUpdateNagleTimer = setTimeout(sendNetworkUpdate, 5000); }
|
||||
|
@ -1419,18 +1388,33 @@ function createMeshCore(agent) {
|
|||
}
|
||||
|
||||
// Called periodically to check if we need to send updates to the server
|
||||
function sendPeriodicServerUpdate(force) {
|
||||
if ((amtMeiConnected != 1) || (force == true)) { // If we are pending MEI connection, hold off on updating the server on self-info
|
||||
if (force == true) { lastSelfInfo = null; }
|
||||
// Update the self information data
|
||||
buildSelfInfo(function (selfInfo) {
|
||||
selfInfoStr = JSON.stringify(selfInfo);
|
||||
if (selfInfoStr != lastSelfInfo) { mesh.SendCommand(selfInfo); lastSelfInfo = selfInfoStr; }
|
||||
function sendPeriodicServerUpdate(flags) {
|
||||
if (meshServerConnectionState == 0) return; // Not connected to server, do nothing.
|
||||
if (!flags) { flags = 0xFFFFFFFF; }
|
||||
|
||||
if (flags & 1) {
|
||||
// If we have a connected MEI, get Intel ME information
|
||||
getAmtInfo(function (meinfo) {
|
||||
try {
|
||||
if (meinfo == null) return;
|
||||
var intelamt = {}, p = false;
|
||||
if (meinfo.Versions && meinfo.Versions.AMT) { intelamt.ver = meinfo.Versions.AMT; p = true; }
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
|
||||
if (meinfo.Flags) { intelamt.flags = meinfo.Flags; p = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
|
||||
if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
|
||||
if (p == true) {
|
||||
var meInfoStr = JSON.stringify({ "action": "coreinfo", "value": obj.meshCoreInfo, "intelamt": intelamt });
|
||||
if (meInfoStr != lastMeInfo) { mesh.SendCommand(meInfoStr); lastMeInfo = meInfoStr; }
|
||||
}
|
||||
} catch (ex) { }
|
||||
});
|
||||
}
|
||||
|
||||
// Update network information
|
||||
sendNetworkUpdateNagle(force);
|
||||
|
||||
if (flags & 2) {
|
||||
// Update network information
|
||||
sendNetworkUpdateNagle(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Get Intel AMT information using MEI
|
||||
|
@ -1492,25 +1476,23 @@ function createMeshCore(agent) {
|
|||
});
|
||||
} catch (e) { amtLmsState = -1; amtLms = null; }
|
||||
|
||||
// Check if the control channel is connected
|
||||
if (mesh.isControlChannelConnected) { handleServerConnection(1); }
|
||||
|
||||
// Setup logged in user monitoring
|
||||
/*
|
||||
require('user-sessions').on('changed', function onUserSessionChanged()
|
||||
{
|
||||
require('user-sessions').enumerateUsers().then(function (users)
|
||||
{
|
||||
obj.loggedInUsers = users.Active;
|
||||
obj.emit('loggedInUsers_Updated');
|
||||
try {
|
||||
var userSession = require('user-sessions');
|
||||
userSession.on('changed', function onUserSessionChanged() {
|
||||
userSession.enumerateUsers().then(function (users) {
|
||||
var u = [], a = users.Active;
|
||||
for (var i in a) { if (a[i].Domain) { u.push(a[i].Domain + '\\' + a[i].Username); } else { u.push(a[i].Username); } }
|
||||
obj.loggedInUsers = u;
|
||||
if (mesh.isControlChannelConnected) { mesh.SendCommand({ "action": "coreinfo", "users": u }); }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
require('user-sessions').emit('changed');
|
||||
require('user-sessions').on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); });
|
||||
require('user-sessions').on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); });
|
||||
userSession.emit('changed');
|
||||
//userSession.on('locked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has LOCKED the desktop'); });
|
||||
//userSession.on('unlocked', function (user) { sendConsoleText('[' + (user.Domain ? user.Domain + '\\' : '') + user.Username + '] has UNLOCKED the desktop'); });
|
||||
} catch (ex) { }
|
||||
*/
|
||||
//console.log('Stopping.');
|
||||
//process.exit();
|
||||
}
|
||||
|
||||
obj.stop = function () {
|
||||
|
@ -1535,7 +1517,8 @@ function createMeshCore(agent) {
|
|||
// KVM Data Channel
|
||||
//
|
||||
|
||||
obj.setupMeiOsAdmin = function(func, state) {
|
||||
obj.setupMeiOsAdmin = function (func, state) {
|
||||
if ((amtMei == null) || (amtMeiConnected != 2)) { return; } // If there is no MEI, don't bother with this.
|
||||
amtMei.getLocalSystemAccount(function (x) {
|
||||
var transport = require('amt-wsman-duk');
|
||||
var wsman = require('amt-wsman');
|
||||
|
|
|
@ -30,7 +30,28 @@ function amt_heci() {
|
|||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('error', function _amtOnError(e)
|
||||
{
|
||||
if(this.Parent._rq.isEmpty())
|
||||
{
|
||||
this.Parent.emit('error', e); // No pending requests, so propagate the error up
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is a pending request, so fail the pending request
|
||||
var user = this.Parent._rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
params.unshift({ Status: -1 }); // Relay an error
|
||||
callback.apply(this.Parent, params);
|
||||
|
||||
if(!this.Parent._rq.isEmpty())
|
||||
{
|
||||
// There are still more pending requests, so try to re-helpconnect MEI
|
||||
this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
}
|
||||
}
|
||||
});
|
||||
this._amt.on('connect', function _amtOnConnect()
|
||||
{
|
||||
this.on('data', function _amtOnData(chunk)
|
||||
|
@ -70,7 +91,8 @@ function amt_heci() {
|
|||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function sendCommand() {
|
||||
this.sendCommand = function sendCommand()
|
||||
{
|
||||
if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
|
||||
var args = [];
|
||||
for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
|
||||
|
@ -278,8 +300,16 @@ function amt_heci() {
|
|||
this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
|
||||
if (header.Data.length == 68) { opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data }); } else { opt.unshift(null); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
|
||||
{
|
||||
if (header.Status == 0 && header.Data.length == 68)
|
||||
{
|
||||
opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data });
|
||||
}
|
||||
else
|
||||
{
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
|
|
|
@ -197,11 +197,18 @@ function UserSessions()
|
|||
{
|
||||
this.parent.hwnd = h;
|
||||
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
this.parent._wts.WTSRegisterSessionNotification(this.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
//this.parent._user32.ACDC_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
//this.parent._user32.BATT_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
//this.parent._user32.DISP_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); // Windows 8+ only, THIS WILL BLOCK ON WIN7
|
||||
// We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification'
|
||||
// from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding
|
||||
// on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately
|
||||
this.immediate = setImmediate(function (self)
|
||||
{
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0);
|
||||
console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val);
|
||||
}, this);
|
||||
});
|
||||
this._messagepump.on('message', function (msg)
|
||||
{
|
||||
|
|
|
@ -30,7 +30,28 @@ function amt_heci() {
|
|||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('error', function _amtOnError(e)
|
||||
{
|
||||
if(this.Parent._rq.isEmpty())
|
||||
{
|
||||
this.Parent.emit('error', e); // No pending requests, so propagate the error up
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is a pending request, so fail the pending request
|
||||
var user = this.Parent._rq.deQueue();
|
||||
var params = user.optional;
|
||||
var callback = user.func;
|
||||
params.unshift({ Status: -1 }); // Relay an error
|
||||
callback.apply(this.Parent, params);
|
||||
|
||||
if(!this.Parent._rq.isEmpty())
|
||||
{
|
||||
// There are still more pending requests, so try to re-helpconnect MEI
|
||||
this.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
}
|
||||
}
|
||||
});
|
||||
this._amt.on('connect', function _amtOnConnect()
|
||||
{
|
||||
this.on('data', function _amtOnData(chunk)
|
||||
|
@ -70,7 +91,8 @@ function amt_heci() {
|
|||
return (ret);
|
||||
};
|
||||
|
||||
this.sendCommand = function sendCommand() {
|
||||
this.sendCommand = function sendCommand()
|
||||
{
|
||||
if (arguments.length < 3 || typeof (arguments[0]) != 'number' || typeof (arguments[1]) != 'object' || typeof (arguments[2]) != 'function') { throw ('invalid parameters'); }
|
||||
var args = [];
|
||||
for (var i = 3; i < arguments.length; ++i) { args.push(arguments[i]); }
|
||||
|
@ -278,8 +300,16 @@ function amt_heci() {
|
|||
this.getLocalSystemAccount = function getLocalSystemAccount(callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt) {
|
||||
if (header.Data.length == 68) { opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data }); } else { opt.unshift(null); }
|
||||
this.sendCommand(103, Buffer.alloc(40), function (header, fn, opt)
|
||||
{
|
||||
if (header.Status == 0 && header.Data.length == 68)
|
||||
{
|
||||
opt.unshift({ user: trim(header.Data.slice(0, 33).toString()), pass: trim(header.Data.slice(33, 67).toString()), raw: header.Data });
|
||||
}
|
||||
else
|
||||
{
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Copyright 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
try { Object.defineProperty(Array.prototype, "peek", { value: function () { return (this.length > 0 ? this[this.length - 1] : undefined); } }); } catch (e) { }
|
||||
|
||||
|
||||
|
||||
function dbus(address, uid)
|
||||
{
|
||||
this._ObjectID = 'linux-dbus';
|
||||
require('events').EventEmitter.call(this, true)
|
||||
.createEvent('signal');
|
||||
Object.defineProperty(this, "uid", { value: uid });
|
||||
this._child = require('child_process').execFile("/bin/sh", ["sh"], { type: require('child_process').SpawnTypes.TERM, uid: uid == null ? -1 : uid });
|
||||
this._child.stdin.write('dbus-monitor --session "type=\'signal\', interface=\'' + address + '\'" | ( while true; do read X; echo "$X"; done )\n');
|
||||
this._child.stdout.dbus = this;
|
||||
this._child.stdout.on('data', function (chunk)
|
||||
{
|
||||
// Parse DBUS Data
|
||||
if (!this.ready) { this.ready = true; return; }
|
||||
|
||||
var lines = [];
|
||||
var tokens = chunk.toString().split('\r\n');
|
||||
for (var i in tokens)
|
||||
{
|
||||
if (tokens[i] == '')
|
||||
{
|
||||
// End of record
|
||||
this.dbus.preParseRecords(lines);
|
||||
lines = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.push(tokens[i]);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.preParseRecords = function (lines)
|
||||
{
|
||||
var record = [];
|
||||
for (var i in lines)
|
||||
{
|
||||
if(lines[i].startsWith('signal '))
|
||||
{
|
||||
if(record.length>0)
|
||||
{
|
||||
this.parseRecords(record);
|
||||
}
|
||||
record = [];
|
||||
}
|
||||
record.push(lines[i]);
|
||||
}
|
||||
if (record.length > 0)
|
||||
{
|
||||
this.parseRecords(record);
|
||||
}
|
||||
}
|
||||
this.parseRecords = function (lines)
|
||||
{
|
||||
if (lines[0].startsWith('signal '))
|
||||
{
|
||||
var signal = {};
|
||||
var sigtokens = lines[0].split(' ');
|
||||
sigtokens.shift();
|
||||
|
||||
for (var i in sigtokens) {
|
||||
var sigitems = sigtokens[i].split('=');
|
||||
if (sigitems.length == 2) {
|
||||
signal[sigitems[0]] = sigitems[1];
|
||||
}
|
||||
}
|
||||
|
||||
lines.shift();
|
||||
signal.data = lines;
|
||||
|
||||
this.parseSignal(signal);
|
||||
}
|
||||
}
|
||||
this.parseSignal = function(signal)
|
||||
{
|
||||
var data = signal.data;
|
||||
signal.data = [];
|
||||
|
||||
for(var i=0; i<data.length; ++i)
|
||||
{
|
||||
if (data[i].startsWith('array '))
|
||||
{
|
||||
signal.data.push([]);
|
||||
for(i=i+1; i<data.length; ++i)
|
||||
{
|
||||
this.parseSignal2(data[i], signal.data.peek());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.parseSignal2(data[i], signal.data);
|
||||
}
|
||||
}
|
||||
|
||||
this.emit('signal', signal);
|
||||
}
|
||||
this.parseSignal2 = function (inputStr, outArray)
|
||||
{
|
||||
if(inputStr.startsWith('string '))
|
||||
{
|
||||
outArray.push(JSON.parse(inputStr.slice(7)));
|
||||
}
|
||||
else if(inputStr.startsWith('boolean '))
|
||||
{
|
||||
outArray.push(JSON.parse(inputStr.slice(8)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = dbus;
|
|
@ -197,11 +197,18 @@ function UserSessions()
|
|||
{
|
||||
this.parent.hwnd = h;
|
||||
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
this.parent._wts.WTSRegisterSessionNotification(this.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
//this.parent._user32.ACDC_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
//this.parent._user32.BATT_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
//this.parent._user32.DISP_H = this.parent._user32.RegisterPowerSettingNotification(this.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0); // Windows 8+ only, THIS WILL BLOCK ON WIN7
|
||||
// We need to yield, and do this in the next event loop pass, becuase we don't want to call 'RegisterPowerSettingNotification'
|
||||
// from the messagepump 'thread', because we are actually on the microstack thread, such that the message pump thread, is holding
|
||||
// on a semaphore for us to return. If we call now, we may deadlock on Windows 7, becuase it will try to notify immediately
|
||||
this.immediate = setImmediate(function (self)
|
||||
{
|
||||
// Now that we have a window handle, we can register it to receive Windows Messages
|
||||
self.parent._wts.WTSRegisterSessionNotification(self.parent.hwnd, NOTIFY_FOR_ALL_SESSIONS);
|
||||
self.parent._user32.ACDC_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_ACDC_POWER_SOURCE, 0);
|
||||
self.parent._user32.BATT_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_BATTERY_PERCENTAGE_REMAINING, 0);
|
||||
self.parent._user32.DISP_H = self.parent._user32.RegisterPowerSettingNotification(self.parent.hwnd, GUID_CONSOLE_DISPLAY_STATE, 0);
|
||||
console.log(self.parent._user32.ACDC_H.Val, self.parent._user32.BATT_H.Val, self.parent._user32.DISP_H.Val);
|
||||
}, this);
|
||||
});
|
||||
this._messagepump.on('message', function (msg)
|
||||
{
|
||||
|
|
34
meshagent.js
34
meshagent.js
|
@ -89,7 +89,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
if (msg.length < 2) return;
|
||||
var cmdid = obj.common.ReadShort(msg, 0);
|
||||
if (cmdid == 11) { // MeshCommand_CoreModuleHash
|
||||
if (msg.length == 4) { ChangeAgentCoreInfo({ caps: 0 }); } // If the agent indicated that no core is running, clear the core information string.
|
||||
if (msg.length == 4) { ChangeAgentCoreInfo({ "caps": 0 }); } // If the agent indicated that no core is running, clear the core information string.
|
||||
// Mesh core hash, sent by agent with the hash of the current mesh core.
|
||||
if (obj.agentCoreCheck == 1000) return; // If we are using a custom core, don't try to update it.
|
||||
// We need to check if the core is current.
|
||||
|
@ -552,7 +552,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
var node = nodes[0];
|
||||
if (node.meshid == obj.dbMeshKey) {
|
||||
// Update the device name & host
|
||||
var newNode = { name: node.name };
|
||||
var newNode = { "name": node.name };
|
||||
if (node.intelamt != null) { newNode.intelamt = node.intelamt; }
|
||||
ChangeAgentCoreInfo(newNode);
|
||||
|
||||
|
@ -575,9 +575,6 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
function ChangeAgentCoreInfo(command) {
|
||||
if ((command == null) || (command == null)) return; // Safety, should never happen.
|
||||
|
||||
// Check capabilities value
|
||||
if (command.caps == null || command.caps == null) { command.caps = 0; } else { if (typeof command.caps != 'number') command.caps = 0; }
|
||||
|
||||
// Check that the mesh exists
|
||||
var mesh = obj.parent.meshes[obj.dbMeshKey];
|
||||
if (mesh == null) return;
|
||||
|
@ -589,30 +586,39 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
|||
if (device.agent) {
|
||||
var changes = [], change = 0;
|
||||
|
||||
//if (command.users) { console.log(command.users); }
|
||||
|
||||
// Check if anything changes
|
||||
if (command.name && (command.name != device.name)) { change = 1; device.name = command.name; changes.push('name'); }
|
||||
if (device.agent.core != command.value) { if ((command.value == null) && (device.agent.core != null)) { delete device.agent.core; } else { device.agent.core = command.value; } change = 1; changes.push('agent core'); }
|
||||
if ((device.agent.caps & 0xFFFFFFE7) != (command.caps & 0xFFFFFFE7)) { device.agent.caps = ((device.agent.caps & 24) + (command.caps & 0xFFFFFFE7)); change = 1; changes.push('agent capabilities'); } // Allow Javascript on the agent to change all capabilities except console and javascript support
|
||||
if ((command.caps != null) && ((device.agent.caps & 0xFFFFFFE7) != (command.caps & 0xFFFFFFE7))) { device.agent.caps = ((device.agent.caps & 24) + (command.caps & 0xFFFFFFE7)); change = 1; changes.push('agent capabilities'); } // Allow Javascript on the agent to change all capabilities except console and javascript support
|
||||
if ((command.osdesc != null) && (device.osdesc != command.osdesc)) { device.osdesc = command.osdesc; change = 1; changes.push('os desc'); }
|
||||
if (command.intelamt) {
|
||||
if (!device.intelamt) { device.intelamt = {}; }
|
||||
if ((command.intelamt.ver != null) && (device.intelamt.ver != command.intelamt.ver)) { device.intelamt.ver = command.intelamt.ver; change = 1; changes.push('AMT version'); }
|
||||
if ((command.intelamt.state != null) && (device.intelamt.state != command.intelamt.state)) { device.intelamt.state = command.intelamt.state; change = 1; changes.push('AMT state'); }
|
||||
if ((command.intelamt.flags != null) && (device.intelamt.flags != command.intelamt.flags)) { device.intelamt.flags = command.intelamt.flags; change = 1; changes.push('AMT flags'); }
|
||||
if ((command.intelamt.host != null) && (device.intelamt.host != command.intelamt.host)) { device.intelamt.host = command.intelamt.host; change = 1; changes.push('AMT host'); }
|
||||
if ((command.intelamt.uuid != null) && (device.intelamt.uuid != command.intelamt.uuid)) { device.intelamt.uuid = command.intelamt.uuid; change = 1; changes.push('AMT uuid'); }
|
||||
if ((command.intelamt.ver != null) && (device.intelamt.ver != command.intelamt.ver)) { changes.push('AMT version'); device.intelamt.ver = command.intelamt.ver; change = 1; }
|
||||
if ((command.intelamt.state != null) && (device.intelamt.state != command.intelamt.state)) { changes.push('AMT state'); device.intelamt.state = command.intelamt.state; change = 1; }
|
||||
if ((command.intelamt.flags != null) && (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;
|
||||
}
|
||||
if ((command.intelamt.host != null) && (device.intelamt.host != command.intelamt.host)) { changes.push('AMT host'); device.intelamt.host = command.intelamt.host; change = 1; }
|
||||
if ((command.intelamt.uuid != null) && (device.intelamt.uuid != command.intelamt.uuid)) { changes.push('AMT uuid'); device.intelamt.uuid = command.intelamt.uuid; change = 1; }
|
||||
}
|
||||
if ((command.users != null) && (device.users != command.users)) { device.users = command.users; change = 1; } // Would be nice not to save this to the db.
|
||||
if (mesh.mtype == 2) {
|
||||
if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; changes.push('host'); }
|
||||
// TODO: Check that the agent has an interface that is the same as the one we got this websocket connection on. Only set if we have a match.
|
||||
}
|
||||
|
||||
// If there are changes, save and event
|
||||
// If there are changes, event the new device
|
||||
if (change == 1) {
|
||||
// Save to the database
|
||||
obj.db.Set(device);
|
||||
|
||||
// Event the node change
|
||||
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id, msg: 'Changed device ' + device.name + ' from mesh ' + mesh.name + ': ' + changes.join(', ') };
|
||||
if (obj.agentInfo.capabilities & 0x20) { event.nolog = 1; } // If this is a temporary device, don't log changes
|
||||
var event = { etype: 'node', action: 'changenode', nodeid: obj.dbNodeKey, domain: domain.id };
|
||||
if (changes.length > 0) { event.msg = 'Changed device ' + device.name + ' from mesh ' + mesh.name + ': ' + changes.join(', '); }
|
||||
if ((obj.agentInfo.capabilities & 0x20) || (changes.length == 0)) { event.nolog = 1; } // If this is a temporary device, don't log changes
|
||||
var device2 = obj.common.Clone(device);
|
||||
if (device2.intelamt && device2.intelamt.pass) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this.
|
||||
event.node = device;
|
||||
|
|
|
@ -946,12 +946,12 @@ function CreateMeshCentralServer(config, args) {
|
|||
8: { id: 8, localname: 'MeshAgent-Linux-XEN-x86-32', rname: 'meshagent', desc: 'XEN x86-64', update: true, amt: false, platform: 'linux' },
|
||||
9: { id: 9, localname: 'meshagent_arm', rname: 'meshagent', desc: 'Linux ARM5', update: true, amt: false, platform: 'linux' },
|
||||
10: { id: 10, localname: 'MeshAgent-Linux-ARM-PlugPC', rname: 'meshagent', desc: 'Linux ARM PlugPC', update: true, amt: false, platform: 'linux' },
|
||||
11: { id: 11, localname: 'MeshAgent-OSX-x86-32', rname: 'meshosx', desc: 'Apple OSX x86-32', update: true, amt: false, platform: 'linux' },
|
||||
11: { id: 11, localname: 'meshagent_osx-x86-32', rname: 'meshosx', desc: 'Apple OSX x86-32', update: true, amt: false, platform: 'linux' },
|
||||
12: { id: 12, localname: 'MeshAgent-Android-x86', rname: 'meshandroid', desc: 'Android x86-32', update: true, amt: false, platform: 'linux' },
|
||||
13: { id: 13, localname: 'meshagent_pogo', rname: 'meshagent', desc: 'Linux ARM PogoPlug', update: true, amt: false, platform: 'linux' },
|
||||
14: { id: 14, localname: 'MeshAgent-Android-APK', rname: 'meshandroid', desc: 'Android Market', update: false, amt: false, platform: 'android' }, // Get this one from Google Play
|
||||
15: { id: 15, localname: 'meshagent_poky', rname: 'meshagent', desc: 'Linux Poky x86-32', update: true, amt: false, platform: 'linux' },
|
||||
16: { id: 16, localname: 'MeshAgent-OSX-x86-64', rname: 'meshagent', desc: 'Apple OSX x86-64', update: true, amt: false, platform: 'osx' },
|
||||
16: { id: 16, localname: 'meshagent_osx-x86-64', rname: 'meshagent', desc: 'Apple OSX x86-64', update: true, amt: false, platform: 'osx' },
|
||||
17: { id: 17, localname: 'MeshAgent-ChromeOS', rname: 'meshagent', desc: 'Google ChromeOS', update: false, amt: false, platform: 'chromeos' }, // Get this one from Chrome store
|
||||
18: { id: 18, localname: 'meshagent_poky64', rname: 'meshagent', desc: 'Linux Poky x86-64', update: true, amt: false, platform: 'linux' },
|
||||
19: { id: 19, localname: 'meshagent_x86_nokvm', rname: 'meshagent', desc: 'Linux x86-32 NoKVM', update: true, amt: true, platform: 'linux' },
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.2.0-w",
|
||||
"version": "0.2.0-y",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
|
|
@ -39,6 +39,14 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
obj.noMouseRotate = false;
|
||||
obj.rotation = 0;
|
||||
// ###END###{DesktopRotation}
|
||||
// ###BEGIN###{DesktopInband}
|
||||
obj.kvmDataSupported = false;
|
||||
obj.onKvmData = null;
|
||||
obj.onKvmDataPending = [];
|
||||
obj.onKvmDataAck = -1;
|
||||
obj.holding = false;
|
||||
obj.lastKeepAlive = Date.now();
|
||||
// ###END###{DesktopInband}
|
||||
|
||||
// ###BEGIN###{DesktopFocus}
|
||||
obj.mx = 0; // Last mouse x position
|
||||
|
@ -138,6 +146,9 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
var supportedEncodings = '';
|
||||
if (obj.useZRLE) supportedEncodings += IntToStr(16);
|
||||
supportedEncodings += IntToStr(0);
|
||||
// ###BEGIN###{DesktopInband}
|
||||
supportedEncodings += IntToStr(1092);
|
||||
// ###END###{DesktopInband}
|
||||
|
||||
obj.send(String.fromCharCode(2, 0) + ShortToStr((supportedEncodings.length / 4) + 1) + supportedEncodings + IntToStr(-223)); // Supported Encodings + Desktop Size
|
||||
|
||||
|
@ -157,13 +168,21 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); }
|
||||
}
|
||||
else if (obj.state == 4) {
|
||||
var c = obj.acc.charCodeAt(0);
|
||||
if (c == 2) {
|
||||
cmdsize = 1; // This is the bell, do nothing.
|
||||
} else if (c == 0) {
|
||||
if (obj.acc.length < 4) return;
|
||||
obj.state = 100 + ReadShort(obj.acc, 2); // Read the number of tiles that are going to be sent, add 100 and use that as our protocol state.
|
||||
cmdsize = 4;
|
||||
switch (obj.acc.charCodeAt(0)) {
|
||||
case 0: // FramebufferUpdate
|
||||
if (obj.acc.length < 4) return;
|
||||
obj.state = 100 + ReadShort(obj.acc, 2); // Read the number of tiles that are going to be sent, add 100 and use that as our protocol state.
|
||||
cmdsize = 4;
|
||||
break;
|
||||
case 2: // This is the bell, do nothing.
|
||||
cmdsize = 1;
|
||||
break;
|
||||
case 3: // This is ServerCutText
|
||||
if (obj.acc.length < 8) return;
|
||||
var len = ReadInt(obj.acc, 4) + 8;
|
||||
if (obj.acc.length < len) return;
|
||||
cmdsize = handleServerCutText(obj.acc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (obj.state > 100 && obj.acc.length >= 12) {
|
||||
|
@ -319,7 +338,31 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
}
|
||||
}
|
||||
|
||||
// ###BEGIN###{DesktopInband}
|
||||
obj.hold = function (holding) {
|
||||
if (obj.holding == holding) return;
|
||||
obj.holding = holding;
|
||||
obj.canvas.fillStyle = '#000000';
|
||||
obj.canvas.fillRect(0, 0, obj.width, obj.height); // Paint black
|
||||
if (obj.holding == false) {
|
||||
// Go back to normal operations
|
||||
// Set canvas size and ask for full screen refresh
|
||||
if ((obj.canvas.canvas.width != obj.width) || (obj.canvas.canvas.height != obj.height)) {
|
||||
obj.canvas.canvas.width = obj.width; obj.canvas.canvas.height = obj.height;
|
||||
if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); } // ???
|
||||
}
|
||||
obj.Send(String.fromCharCode(3, 0, 0, 0, 0, 0) + ShortToStr(obj.width) + ShortToStr(obj.height)); // FramebufferUpdateRequest
|
||||
} else {
|
||||
obj.UnGrabMouseInput();
|
||||
obj.UnGrabKeyInput();
|
||||
}
|
||||
}
|
||||
// ###END###{DesktopInband}
|
||||
|
||||
function _putImage(i, x, y) {
|
||||
// ###BEGIN###{DesktopInband}
|
||||
if (obj.holding == true) return;
|
||||
// ###END###{DesktopInband}
|
||||
// ###BEGIN###{DesktopRotation}
|
||||
var xx = _arotX(x, y);
|
||||
y = _arotY(x, y);
|
||||
|
@ -416,6 +459,11 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
obj.setRotation = function (x) {
|
||||
while (x < 0) { x += 4; }
|
||||
var newrotation = x % 4;
|
||||
//console.log('hard-rot: ' + newrotation);
|
||||
// ###BEGIN###{DesktopInband}
|
||||
if (obj.holding == true) { obj.rotation = newrotation; return; }
|
||||
// ###END###{DesktopInband}
|
||||
|
||||
if (newrotation == obj.rotation) return true;
|
||||
var rw = obj.canvas.canvas.width;
|
||||
var rh = obj.canvas.canvas.height;
|
||||
|
@ -451,6 +499,9 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
function _fixColor(c) { return (c > 127) ? (c + 32) : c; }
|
||||
|
||||
function _SendRefresh() {
|
||||
// ###BEGIN###{DesktopInband}
|
||||
if (obj.holding == true) return;
|
||||
// ###END###{DesktopInband}
|
||||
// ###BEGIN###{DesktopFocus}
|
||||
if (obj.focusmode > 0) {
|
||||
// Request only pixels around the last mouse position
|
||||
|
@ -477,6 +528,11 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
// ###BEGIN###{Inflate}
|
||||
obj.inflate.inflateReset();
|
||||
// ###END###{Inflate}
|
||||
// ###BEGIN###{DesktopInband}
|
||||
obj.onKvmDataPending = [];
|
||||
obj.onKvmDataAck = -1;
|
||||
obj.kvmDataSupported = false;
|
||||
// ###END###{DesktopInband}
|
||||
for (var i in obj.sparecache) { delete obj.sparecache[i]; }
|
||||
}
|
||||
|
||||
|
@ -555,6 +611,43 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
|
|||
else { obj.send(String.fromCharCode(4, d, 0, 0) + IntToStr(k)); }
|
||||
}
|
||||
|
||||
function handleServerCutText(acc) {
|
||||
if (acc.length < 8) return 0;
|
||||
var len = ReadInt(obj.acc, 4) + 8;
|
||||
if (acc.length < len) return 0;
|
||||
// ###BEGIN###{DesktopInband}
|
||||
if (obj.onKvmData != null) {
|
||||
var d = acc.substring(8, len);
|
||||
if ((d.length >= 16) && (d.substring(0, 15) == '\0KvmDataChannel')) {
|
||||
if (obj.kvmDataSupported == false) { obj.kvmDataSupported = true; console.log('KVM Data Channel Supported.'); }
|
||||
if (((obj.onKvmDataAck == -1) && (d.length == 16)) || (d.charCodeAt(15) != 0)) { obj.onKvmDataAck = true; }
|
||||
//if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Recv(' + (d.length - 16) + '): ' + d.substring(16)); }
|
||||
if (d.length > 16) { obj.onKvmData(d.substring(16)); } // Event the data and ack
|
||||
if ((obj.onKvmDataAck == true) && (obj.onKvmDataPending.length > 0)) { obj.sendKvmData(obj.onKvmDataPending.shift()); } // Send pending data
|
||||
}
|
||||
}
|
||||
// ###END###{DesktopInband}
|
||||
return len;
|
||||
}
|
||||
|
||||
// ###BEGIN###{DesktopInband}
|
||||
obj.sendKvmData = function (x) {
|
||||
if (obj.onKvmDataAck !== true) {
|
||||
obj.onKvmDataPending.push(x);
|
||||
} else {
|
||||
if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Send(' + x.length + '): ' + x); }
|
||||
x = '\0KvmDataChannel\0' + x;
|
||||
obj.Send(String.fromCharCode(6, 0, 0, 0) + IntToStr(x.length) + x);
|
||||
obj.onKvmDataAck = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Send a HWKVM keep alive if it's not been sent in the last 5 seconds.
|
||||
obj.sendKeepAlive = function () {
|
||||
if (obj.lastKeepAlive < Date.now() - 5000) { obj.lastKeepAlive = Date.now(); obj.Send(String.fromCharCode(6, 0, 0, 0) + IntToStr(16) + '\0KvmDataChannel\0'); }
|
||||
}
|
||||
// ###END###{DesktopInband}
|
||||
|
||||
obj.SendCtrlAltDelMsg = function () { obj.sendcad(); }
|
||||
obj.sendcad = function () { obj.sendkey([[0xFFE3, 1], [0xFFE9, 1], [0xFFFF, 1], [0xFFFF, 0], [0xFFE9, 0], [0xFFE3, 0]]); } // Control down, Alt down, Delete down, Delete up , Alt up , Control up
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -144,8 +144,8 @@
|
|||
</div>
|
||||
<div id=p1 style=display:none>
|
||||
<div style="float:right" id="devListToolbarViewIcons">
|
||||
<div id=devViewButton1 class="viewSelector" onclick=onDeviceViewChange(1) title="Columns"><div class="viewSelector1"></div></div>
|
||||
<div id=devViewButton2 class=viewSelector onclick=onDeviceViewChange(2) title="List"><div class="viewSelector2"></div></div>
|
||||
<div id=devViewButton1 class="viewSelector" onclick=onDeviceViewChange(1) title="Columns"><div class="viewSelector2"></div></div>
|
||||
<div id=devViewButton2 class=viewSelector onclick=onDeviceViewChange(2) title="List"><div class="viewSelector1"></div></div>
|
||||
<div id=devViewButton3 class=viewSelector onclick=onDeviceViewChange(3) title="Desktops"><div class="viewSelector3"></div></div>
|
||||
<div id=devViewButton4 class=viewSelector onclick=onDeviceViewChange(4) title="Map"><div class="viewSelector4"></div></div>
|
||||
</div><div><h1>My Devices</h1></div>
|
||||
|
@ -1361,12 +1361,15 @@
|
|||
for (var i in nodes) { if (nodes[i]._id == message.event.nodeid) { index = i; break; } }
|
||||
if (index != -1) {
|
||||
var node = nodes[index];
|
||||
console.log(node);
|
||||
|
||||
// Change the node
|
||||
node.name = message.event.node.name;
|
||||
node.rname = message.event.node.rname;
|
||||
node.users = message.event.node.users;
|
||||
node.host = message.event.node.host;
|
||||
node.desc = message.event.node.desc;
|
||||
node.osdesc = message.event.node.osdesc;
|
||||
node.publicip = message.event.node.publicip;
|
||||
node.iploc = message.event.node.iploc;
|
||||
node.wifiloc = message.event.node.wifiloc;
|
||||
|
@ -1892,6 +1895,7 @@
|
|||
desk.m.bpp = 1;
|
||||
desk.m.useZRLE = true;
|
||||
desk.m.showmouse = true;
|
||||
desk.m.onKvmData = function (data) { console.log('KVMData: ' + data); };
|
||||
//desk.m.onScreenSizeChange = deskAdjust;
|
||||
desk.Start(nodeid, 16994, '*', '*', 0);
|
||||
desk.contype = 2;
|
||||
|
@ -2075,8 +2079,8 @@
|
|||
function addAgentToMesh(meshid) {
|
||||
if (xxdialogMode) return;
|
||||
var mesh = meshes[meshid], x = '';
|
||||
//x += addHtmlValue('Operating System', '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux</option><option value=2>Apple OSX</option><option value=3>Windows (UnInstall)</option><option value=4>Linux (UnInstall)</option></select>') + '<hr>';
|
||||
x += addHtmlValue('Operating System', '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux</option><option value=3>Windows (UnInstall)</option><option value=4>Linux (UnInstall)</option></select>') + '<hr>';
|
||||
x += addHtmlValue('Operating System', '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux</option><option value=2>Apple OSX</option><option value=3>Windows (UnInstall)</option><option value=4>Linux (UnInstall)</option></select>') + '<hr>';
|
||||
//x += addHtmlValue('Operating System', '<select id=aginsSelect onchange=addAgentToMeshClick() style=width:236px><option value=0>Windows</option><option value=1>Linux</option><option value=3>Windows (UnInstall)</option><option value=4>Linux (UnInstall)</option></select>') + '<hr>';
|
||||
|
||||
// Windows agent install
|
||||
//x += "<div id=agins_windows>To add a new computer to mesh " + EscapeHtml(mesh.name) + ", download the mesh agent and configuration file and install the agent on the computer to manage.<br /><br />";
|
||||
|
@ -2093,7 +2097,7 @@
|
|||
|
||||
// OSX agent install
|
||||
x += "<div id=agins_osx style=display:none>To add a new computer to mesh " + EscapeHtml(mesh.name) + ", download the mesh agent and install it the computer to manage. This agent installer has server and mesh information embedded within it.<br /><br />";
|
||||
x += addHtmlValue('Mesh Agent', '<a href="meshosxagent?id=3&meshid=' + meshid.split('/')[2] + '" target="_blank" title="64bit version of OSX Mesh Agent">OSX Agent (64bit)</a>');
|
||||
x += addHtmlValue('Mesh Agent', '<a href="meshosxagent?id=16&meshid=' + meshid.split('/')[2] + '" target="_blank" title="64bit version of OSX Mesh Agent">OSX Agent (64bit) - TEST BUILD</a>');
|
||||
x += "</div>";
|
||||
|
||||
// Windows agent uninstall
|
||||
|
@ -3067,6 +3071,12 @@
|
|||
// Attribute: Intel AMT
|
||||
//if (node.intelamt && node.intelamt.user) { x += addDeviceAttribute('Intel® AMT', node.intelamt.user); }
|
||||
|
||||
// Operating system description
|
||||
if (node.osdesc) { x += addDeviceAttribute('Operating System', node.osdesc); }
|
||||
|
||||
// Active Users
|
||||
if (node.users && node.conn && (node.users.length > 0) && (node.conn & 1)) { x += addDeviceAttribute('Active User' + ((node.users.length > 1)?'s':''), node.users.join(', ')); }
|
||||
|
||||
// Attribute: Connectivity (Only show this if more than just the agent is connected).
|
||||
var connectivity = node.conn;
|
||||
if (connectivity && connectivity > 1) {
|
||||
|
@ -3583,6 +3593,7 @@
|
|||
desktop.m.useZRLE = (desktopsettings.encoding < 3);
|
||||
desktop.m.showmouse = desktopsettings.showmouse;
|
||||
desktop.m.onScreenSizeChange = deskAdjust;
|
||||
desktop.m.onKvmData = function (data) { console.log('KVMData: ' + data); };
|
||||
desktop.Start(desktopNode._id, 16994, '*', '*', 0);
|
||||
desktop.contype = 2;
|
||||
} else {
|
||||
|
|
|
@ -1636,11 +1636,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
if ((domain == null) || (req.query.id == null)) { res.sendStatus(404); return; }
|
||||
|
||||
// If required, check if this user has rights to do this
|
||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true) && (req.session.userid == null)) { res.sendStatus(401); console.log('2'); return; }
|
||||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true) && (req.session.userid == null)) { res.sendStatus(401); return; }
|
||||
|
||||
// Send a specific mesh agent back
|
||||
var argentInfo = obj.parent.meshAgentBinaries[req.query.id];
|
||||
if ((argentInfo == null) || (req.query.meshid == null)) { res.sendStatus(404); console.log('3'); return; }
|
||||
if ((argentInfo == null) || (req.query.meshid == null)) { res.sendStatus(404); return; }
|
||||
|
||||
// We are going to embed the .msh file into the Windows executable (signed or not).
|
||||
// First, fetch the mesh object to build the .msh file
|
||||
|
@ -1651,8 +1651,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
|
|||
if ((obj.parent.config.settings != null) && (obj.parent.config.settings.lockagentdownload == true)) {
|
||||
var user = obj.users[req.session.userid];
|
||||
var escUserId = obj.common.escapeFieldName(user._id);
|
||||
if ((user == null) || (mesh.links[escUserId] == null) || ((mesh.links[escUserId].rights & 1) == 0)) { res.sendStatus(401); console.log('4'); return; }
|
||||
if (domain.id != mesh.domain) { res.sendStatus(401); console.log('5'); return; }
|
||||
if ((user == null) || (mesh.links[escUserId] == null) || ((mesh.links[escUserId].rights & 1) == 0)) { res.sendStatus(401); return; }
|
||||
if (domain.id != mesh.domain) { res.sendStatus(401); return; }
|
||||
}
|
||||
|
||||
var meshidhex = new Buffer(req.query.meshid.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
|
||||
|
|
Loading…
Reference in New Issue