Improved MeshCmd, added audit log support.
This commit is contained in:
parent
b831f097b8
commit
2f3a02d1fd
Binary file not shown.
Binary file not shown.
|
@ -91,7 +91,7 @@ function run(argv) {
|
|||
//console.log('addedModules = ' + JSON.stringify(addedModules));
|
||||
var actionpath = 'meshaction.txt';
|
||||
if (args.actionfile != null) { actionpath = args.actionfile; }
|
||||
var actions = ['HELP', 'ROUTE', 'AMTLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER'];
|
||||
var actions = ['HELP', 'ROUTE', 'AMTLMS', 'AMTLOADWEBAPP', 'AMTLOADSMALLWEBAPP', 'AMTLOADLARGEWEBAPP', 'AMTCLEARWEBAPP', 'AMTSTORAGESTATE', 'AMTINFO', 'AMTVERSIONS', 'AMTHASHES', 'AMTSAVESTATE', 'AMTSCRIPT', 'AMTUUID', 'AMTCCM', 'AMTDEACTIVATE', 'SMBIOS', 'RAWSMBIOS', 'MESHCOMMANDER', 'AMTAUDITLOG'];
|
||||
|
||||
// Load the action file
|
||||
var actionfile = null;
|
||||
|
@ -142,6 +142,7 @@ function run(argv) {
|
|||
console.log('\r\nValid local or remote actions:');
|
||||
console.log(' MeshCommander - Launch a local MeshCommander web server.');
|
||||
console.log(' AmtUUID - Show Intel AMT unique identifier.');
|
||||
console.log(' AmtAuditLog - Show the Intel AMT audit log.');
|
||||
console.log(' AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.');
|
||||
console.log(' AmtClearWebApp - Clear everything from Intel AMT web storage.');
|
||||
console.log(' AmtStorageState - Show contents of the Intel AMT web storage.');
|
||||
|
@ -230,6 +231,14 @@ function run(argv) {
|
|||
console.log('This action launched a local web server that hosts MeshCommander, a Intel AMT management console.');
|
||||
console.log('\r\nPossible arguments:\r\n');
|
||||
console.log(' --localport [port] Local port used for the web server, 3000 is default.');
|
||||
} else if (action == 'amtauditlog') {
|
||||
console.log('AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json');
|
||||
console.log('\r\nPossible arguments:\r\n');
|
||||
console.log(' --output [filename] The output file for the Intel AMT state in JSON format.');
|
||||
console.log(' --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.');
|
||||
console.log(' --user [username] The Intel AMT login username, admin is default.');
|
||||
console.log(' --pass [password] The Intel AMT login password.');
|
||||
console.log(' --tls Specifies that TLS must be used.');
|
||||
} else {
|
||||
actions.shift();
|
||||
console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
|
||||
|
@ -373,15 +382,61 @@ function run(argv) {
|
|||
// Deactivate CCM
|
||||
debug(1, "Settings: " + JSON.stringify(settings));
|
||||
deactivateCCM();
|
||||
} else if (settings.action == 'meshcommander') {
|
||||
// Start MeshCommander
|
||||
} else if (settings.action == 'meshcommander') { // Start MeshCommander
|
||||
startMeshCommander();
|
||||
} else if (settings.action == 'amtauditlog') { // Read the Intel AMT audit log
|
||||
if (settings.hostname != null) {
|
||||
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||||
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||||
} else { settings.hostname = '127.0.0.1'; }
|
||||
readAmtAuditLog();
|
||||
} else {
|
||||
console.log('Invalid \"action\" specified.'); exit(1); return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Intel AMT Audit Log
|
||||
//
|
||||
|
||||
function readAmtAuditLog() {
|
||||
// See if MicroLMS needs to be started
|
||||
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) {
|
||||
settings.noconsole = true; startLms(readAmtAuditLogEx);
|
||||
} else {
|
||||
readAmtAuditLogEx(9999);
|
||||
}
|
||||
}
|
||||
|
||||
function readAmtAuditLogEx(x) {
|
||||
if (x == 9999) {
|
||||
var transport = require('amt-wsman-duk');
|
||||
var wsman = require('amt-wsman');
|
||||
var amt = require('amt');
|
||||
wsstack = new wsman(transport, settings.hostname, settings.tls ? 16993 : 16992, settings.username, settings.password, settings.tls);
|
||||
amtstack = new amt(wsstack);
|
||||
amtstack.GetAuditLog(readAmtAuditLogEx2);
|
||||
} else {
|
||||
osamtstack.GetAuditLog(readAmtAuditLogEx2);
|
||||
}
|
||||
}
|
||||
|
||||
function readAmtAuditLogEx2(stack, response, status) {
|
||||
if (status != 200) {
|
||||
console.log('Unable to get audit log, status = ' + status + '.');
|
||||
} else {
|
||||
var out = '';
|
||||
for (var i in response) {
|
||||
var name = ((response[i].Initiator != '')?(response[i].Initiator + ': '):'')
|
||||
out += (response[i].Time + ' - ' + name + response[i].Event + '\r\n');
|
||||
}
|
||||
if (settings.output == null) { console.log(out); } else { var file = fs.openSync(settings.output, 'w'); fs.writeSync(file, new Buffer(out, 'utf8')); fs.closeSync(file); }
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// MeshCommander local web server
|
||||
//
|
||||
|
@ -397,27 +452,18 @@ function startMeshCommander() {
|
|||
var http = require('http');
|
||||
webServer = http.createServer();
|
||||
webServer.listen(settings.localport);
|
||||
webServer.wsList = {};
|
||||
webServer.wsListIndex = 0;
|
||||
webServer.on('upgrade', function (req, socket, head) {
|
||||
//console.log("WebSocket for " + req.url.split('?')[0]);
|
||||
switch (req.url.split('?')[0]) {
|
||||
case '/webrelay.ashx': // MeshCommander relay channel
|
||||
var ws = socket.upgradeWebSocket();
|
||||
socket.ws = ws;
|
||||
ws.wsIndex = ++webServer.wsListIndex;
|
||||
webServer.wsList[ws.wsIndex] = ws;
|
||||
ws.pause();
|
||||
|
||||
// When data is received from the web socket, forward the data into the associated TCP connection.
|
||||
// If the TCP connection is pending, buffer up the data until it connects.
|
||||
ws.on('data', function (data) {
|
||||
//console.log('Data relay --> ' + data.length + ': ' + data.toString() + '\r\n');
|
||||
ws.forwardclient.write(data); // Forward data to the associated TCP connection.
|
||||
});
|
||||
|
||||
// If the web socket is closed, close the associated TCP connection.
|
||||
ws.on('close', function (req) {
|
||||
//console.log('Closed websocket.');
|
||||
if (ws.forwardclient) { try { ws.forwardclient.destroy(); } catch (e) { } }
|
||||
});
|
||||
|
||||
// We got a new web socket connection, initiate a TCP connection to the target Intel AMT host/port.
|
||||
var webargs = parseUrlArguments(req.url);
|
||||
if (webargs.p) { webargs.p = parseInt(webargs.p); }
|
||||
|
@ -429,36 +475,16 @@ function startMeshCommander() {
|
|||
// If this is TCP (without TLS) set a normal TCP socket
|
||||
var net = require('net');
|
||||
ws.forwardclient = net.connect({ host: webargs.host, port: webargs.port })
|
||||
ws.forwardclient.on('connect', function () { this.pipe(this.ws); this.ws.pipe(this); });
|
||||
ws.forwardclient.ws = ws;
|
||||
ws.forwardclient.on('connect', function () { this.ws.resume(); });
|
||||
} else {
|
||||
// If TLS is going to be used, setup a TLS socket
|
||||
var tls = require('tls');
|
||||
var tlsoptions = { host: webargs.host, port: webargs.port, secureProtocol: ((webargs.tls1only == 1) ? 'TLSv1_method' : 'SSLv23_method'), rejectUnauthorized: false };
|
||||
ws.forwardclient = tls.connect(tlsoptions, function () { this.ws.resume(); });
|
||||
ws.forwardclient = tls.connect(tlsoptions, function () { this.pipe(this.ws); this.ws.pipe(this); });
|
||||
ws.forwardclient.ws = ws;
|
||||
}
|
||||
|
||||
// When we receive data on the TCP connection, forward it back into the web socket connection.
|
||||
ws.forwardclient.on('data', function (data) {
|
||||
//console.log('Data relay <-- ' + data.length + ': ' + data.toString() + '\r\n');
|
||||
try { this.ws.write(data); } catch (e) { }
|
||||
});
|
||||
|
||||
// If the TCP connection closes, disconnect the associated web socket.
|
||||
ws.forwardclient.on('close', function () {
|
||||
//console.log('TCP/TLS disconnected.');
|
||||
try { this.ws.end(); } catch (e) { }
|
||||
try { this.end(); } catch (e) { }
|
||||
});
|
||||
|
||||
// If the TCP connection causes an error, disconnect the associated web socket.
|
||||
ws.forwardclient.on('error', function (err) {
|
||||
//console.log('TCP/TLS disconnected with error', err);
|
||||
try { this.ws.end(); } catch (e) { }
|
||||
try { this.end(); } catch (e) { }
|
||||
});
|
||||
|
||||
break;
|
||||
default:
|
||||
socket.end();
|
||||
|
@ -1129,5 +1155,11 @@ function parseUrlArguments(url) {
|
|||
return r;
|
||||
}
|
||||
|
||||
// Remove a element from a array
|
||||
function removeItemFromArray(array, element) {
|
||||
const index = array.indexOf(element);
|
||||
if (index !== -1) { array.splice(index, 1); }
|
||||
}
|
||||
|
||||
// Run MeshCmd
|
||||
try { run(process.argv); } catch (e) { console.log('ERROR: ' + e); }
|
||||
|
|
|
@ -75,10 +75,10 @@ function createMeshCore(agent) {
|
|||
// Try to load up the MEI module
|
||||
try {
|
||||
var amtMeiLib = require('amt-mei');
|
||||
amtMeiConnected = 1;
|
||||
amtMei = new amtMeiLib();
|
||||
amtMei.on('error', function (e) { amtMeiLib = null; amtMei = null; sendPeriodicServerUpdate(); });
|
||||
amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); });
|
||||
amtMeiConnected = 2;
|
||||
//amtMei.on('connect', function () { amtMeiConnected = 2; sendPeriodicServerUpdate(); });
|
||||
} catch (e) { amtMeiLib = null; amtMei = null; amtMeiConnected = -1; }
|
||||
|
||||
// Try to load up the WIFI scanner
|
||||
|
@ -869,11 +869,11 @@ function createMeshCore(agent) {
|
|||
break;
|
||||
}
|
||||
case 'selfinfo': { // Return self information block
|
||||
buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' '), sessionid); });
|
||||
buildSelfInfo(function (info) { sendConsoleText(objToString(info, 0, ' ', true), sessionid); });
|
||||
break;
|
||||
}
|
||||
case 'args': { // Displays parsed command arguments
|
||||
response = 'args ' + objToString(args, 0, ' ');
|
||||
response = 'args ' + objToString(args, 0, ' ', true);
|
||||
break;
|
||||
}
|
||||
case 'print': { // Print a message on the mesh agent console, does nothing when running in the background
|
||||
|
@ -1045,7 +1045,7 @@ function createMeshCore(agent) {
|
|||
case 'amt': { // Show Intel AMT status
|
||||
getAmtInfo(function (state) {
|
||||
var resp = 'Intel AMT not detected.';
|
||||
if (state != null) { resp = objToString(state, 0, ' '); }
|
||||
if (state != null) { resp = objToString(state, 0, ' ', true); }
|
||||
sendConsoleText(resp, sessionid);
|
||||
});
|
||||
break;
|
||||
|
@ -1053,7 +1053,11 @@ function createMeshCore(agent) {
|
|||
case 'netinfo': { // Show network interface information
|
||||
//response = objToString(mesh.NetInfo, 0, ' ');
|
||||
var interfaces = require('os').networkInterfaces();
|
||||
response = objToString(interfaces, 0, ' ');
|
||||
response = objToString(interfaces, 0, ' ', true);
|
||||
break;
|
||||
}
|
||||
case 'netinfo2': { // Show network interface information
|
||||
response = objToString(mesh.NetInfo, 0, ' ', true);
|
||||
break;
|
||||
}
|
||||
case 'wakeonlan': { // Send wake-on-lan
|
||||
|
@ -1215,7 +1219,7 @@ function createMeshCore(agent) {
|
|||
amtMei.getVersion(function (val) { amtMeiTmpState.Versions = {}; for (var version in val.Versions) { amtMeiTmpState.Versions[val.Versions[version].Description] = val.Versions[version].Version; } });
|
||||
amtMei.getProvisioningMode(function (result) { amtMeiTmpState.ProvisioningMode = result.mode; });
|
||||
amtMei.getProvisioningState(function (result) { amtMeiTmpState.ProvisioningState = result.state; });
|
||||
amtMei.getEHBCState(function (result) { if (result.EHBC == true) { amtMeiTmpState.Flags += 1; } });
|
||||
amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } });
|
||||
amtMei.getControlMode(function (result) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } });
|
||||
//amtMei.getMACAddresses(function (result) { amtMeiTmpState.mac = result; });
|
||||
amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } });
|
||||
|
|
|
@ -18,7 +18,6 @@ var Q = require('queue');
|
|||
function amt_heci() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
var heci = require('heci');
|
||||
|
||||
|
|
|
@ -633,7 +633,7 @@ function AmtStackCreateService(wsmanStack) {
|
|||
2003: 'Security Audit Log Enabled',
|
||||
2004: 'Security Audit Log Exported',
|
||||
2005: 'Security Audit Log Recovered',
|
||||
2100: 'Intel® ME Time Set',
|
||||
2100: 'Intel(R) ME Time Set',
|
||||
2200: 'TCPIP Parameters Set',
|
||||
2201: 'Host Name Set',
|
||||
2202: 'Domain Name Set',
|
||||
|
@ -742,12 +742,12 @@ function AmtStackCreateService(wsmanStack) {
|
|||
}
|
||||
if (x['InitiatorType'] == 2) {
|
||||
// Local
|
||||
x['Initiator'] = '<i>Local</i>';
|
||||
x['Initiator'] = 'Local';
|
||||
ptr = 5;
|
||||
}
|
||||
if (x['InitiatorType'] == 3) {
|
||||
// KVM Default Port
|
||||
x['Initiator'] = '<i>KVM Default Port</i>';
|
||||
x['Initiator'] = 'KVM Default Port';
|
||||
ptr = 5;
|
||||
}
|
||||
|
||||
|
|
|
@ -290,11 +290,8 @@ function lme_heci(options) {
|
|||
var notify = null;
|
||||
try { notify = xmlParser.ParseWsman(httpData); } catch (e) { }
|
||||
|
||||
// Translate the event
|
||||
var notifyString = _lmsNotifyToString(notify);
|
||||
|
||||
// Event the http data
|
||||
if (notify != null) { this.LMS.emit('notify', notify, channel.options, notifyString); }
|
||||
if (notify != null) { this.LMS.emit('notify', notify, channel.options, _lmsNotifyToString(notify), _lmsNotifyToCode(notify)); }
|
||||
|
||||
// Send channel close
|
||||
var buffer = Buffer.alloc(5);
|
||||
|
@ -437,6 +434,13 @@ function parseHttp(httpData) {
|
|||
return null;
|
||||
}
|
||||
|
||||
function _lmsNotifyToCode(notify) {
|
||||
if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
|
||||
var msgid = notify.Body.MessageID;
|
||||
try { msgid += '-' + notify.Body.MessageArguments[0]; } catch (e) { }
|
||||
return msgid;
|
||||
}
|
||||
|
||||
function _lmsNotifyToString(notify) {
|
||||
if ((notify == null) || (notify.Body == null) || (notify.Body.MessageID == null)) return null;
|
||||
var msgid = notify.Body.MessageID;
|
||||
|
@ -520,7 +524,7 @@ var lmsEvents = {
|
|||
"iAMT0055-0": "User Notification Alert - Provisioning state change notification - Pre-configuration.",
|
||||
"iAMT0055-1": "User Notification Alert - Provisioning state change notification - In configuration.",
|
||||
"iAMT0055-2": "User Notification Alert - Provisioning state change notification - Post-configuration.",
|
||||
"iAMT0055-3": "User Notification Alert - Provisioning state change notification - unprovision process has started.",
|
||||
"iAMT0055-3": "User Notification Alert - Provisioning state change notification - Unprovision process has started.",
|
||||
"iAMT0056": "User Notification Alert - System Defense change notification.",
|
||||
"iAMT0057": "User Notification Alert - Network State change notification.",
|
||||
"iAMT0058": "User Notification Alert - Remote Access change notification.",
|
||||
|
|
|
@ -18,24 +18,20 @@ var Q = require('queue');
|
|||
function amt_heci() {
|
||||
var emitterUtils = require('events').inherits(this);
|
||||
emitterUtils.createEvent('error');
|
||||
emitterUtils.createEvent('connect');
|
||||
|
||||
var heci = require('heci');
|
||||
|
||||
this._ObjectID = "pthi";
|
||||
this._rq = new Q();
|
||||
this._setupPTHI = function _setupPTHI()
|
||||
{
|
||||
this._setupPTHI = function _setupPTHI() {
|
||||
this._amt = heci.create();
|
||||
this._amt.BiosVersionLen = 65;
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('connect', function _amtOnConnect()
|
||||
{
|
||||
this.on('data', function _amtOnData(chunk)
|
||||
{
|
||||
this._amt.on('connect', function _amtOnConnect() {
|
||||
this.on('data', function _amtOnData(chunk) {
|
||||
//console.log("Received: " + chunk.length + " bytes");
|
||||
var header = this.Parent.getCommand(chunk);
|
||||
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
|
||||
|
@ -47,14 +43,12 @@ function amt_heci() {
|
|||
params.unshift(header);
|
||||
callback.apply(this.Parent, params);
|
||||
|
||||
if(this.Parent._rq.isEmpty())
|
||||
{
|
||||
if (this.Parent._rq.isEmpty()) {
|
||||
// No More Requests, we can close PTHI
|
||||
this.Parent._amt.disconnect();
|
||||
this.Parent._amt = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Send the next request
|
||||
this.write(this.Parent._rq.peekQueue().send);
|
||||
}
|
||||
|
@ -79,10 +73,9 @@ function amt_heci() {
|
|||
var header = Buffer.from('010100000000000000000000', 'hex');
|
||||
header.writeUInt32LE(arguments[0] | 0x04000000, 4);
|
||||
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
|
||||
this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args , send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]]))});
|
||||
this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
|
||||
|
||||
if(!this._amt)
|
||||
{
|
||||
if (!this._amt) {
|
||||
this._setupPTHI();
|
||||
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
}
|
||||
|
@ -94,7 +87,7 @@ function amt_heci() {
|
|||
this.sendCommand(26, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen); ++i) {
|
||||
val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
|
||||
v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
|
||||
}
|
||||
|
|
|
@ -563,15 +563,7 @@
|
|||
<div id="d7meshkvm">
|
||||
<h4 style="width:100%;border-bottom:1px solid gray">Mesh Agent Remote Desktop</h4>
|
||||
<div style="margin:3px 0 3px 0">
|
||||
<select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl">
|
||||
<option value=50>50%</option>
|
||||
<option value=40>40%</option>
|
||||
<option selected=selected value=30>30%</option>
|
||||
<option value=20>20%</option>
|
||||
<option value=10>10%</option>
|
||||
<option value=5>5%</option>
|
||||
<option value=1>1%</option>
|
||||
</select>
|
||||
<select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl"></select>
|
||||
<div style="height:20px">Quality</div>
|
||||
</div>
|
||||
<div style="margin:3px 0 3px 0">
|
||||
|
@ -3075,9 +3067,13 @@
|
|||
}
|
||||
|
||||
function applyDesktopSettings() {
|
||||
var r = '', ops = (features & 512)?[100,80,50,40,30,20,10,5,1]:[50,40,30,20,10,5,1];
|
||||
for (var i in ops) { r += '<option value=' + ops[i] + '>' + ops[i] + '%</option>'; }
|
||||
QH('d7bitmapquality', r);
|
||||
d7desktopmode.value = desktopsettings.encoding;
|
||||
d7showfocus.checked = desktopsettings.showfocus;
|
||||
d7showcursor.checked = desktopsettings.showmouse;
|
||||
d7bitmapquality.value = 40; // Default value
|
||||
d7bitmapquality.value = desktopsettings.quality;
|
||||
d7bitmapscaling.value = desktopsettings.scaling;
|
||||
QV('deskFocusBtn', (desktop != null) && (desktop.contype == 2) && (desktop.state != 0) && (desktopsettings.showfocus));
|
||||
|
|
|
@ -682,6 +682,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
|||
if ((obj.parent.mailserver != null) && (obj.parent.certificates.CommonName != null) && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly != true)) { features += 64; } // Email invites
|
||||
if (obj.args.webrtc == true) { features += 128; } // Enable WebRTC (Default false for now)
|
||||
if (obj.args.clickonce !== false) { features += 256; } // Enable ClickOnce (Default true)
|
||||
if (obj.args.allowhighqualitydesktop == true) { features += 512; } // Enable AllowHighQualityDesktop (Default false)
|
||||
|
||||
// Send the master web application
|
||||
if ((!obj.args.user) && (obj.args.nousers != true) && (nologout == false)) { logoutcontrol += ' <a href=' + domain.url + 'logout?' + Math.random() + ' style=color:white>Logout</a>'; } // If a default user is in use or no user mode, don't display the logout button
|
||||
|
|
Loading…
Reference in New Issue