diff --git a/MeshCentralServer.njsproj b/MeshCentralServer.njsproj
index b904f8cf..81ac6309 100644
--- a/MeshCentralServer.njsproj
+++ b/MeshCentralServer.njsproj
@@ -98,7 +98,7 @@
-
+
diff --git a/amthelloserver.js b/amtprovisioningserver.js
similarity index 99%
rename from amthelloserver.js
rename to amtprovisioningserver.js
index b6771273..65a48450 100644
--- a/amthelloserver.js
+++ b/amtprovisioningserver.js
@@ -17,7 +17,7 @@
// Construct the Intel AMT hello server. This is used for Intel AMT bare-metal activation on the local LAN.
// This server can receive a notification from Intel AMT and attempt activation.
// In Intel documentation, this is called the Setup and Configuration Application (SCA)
-module.exports.CreateAmtHelloServer = function (parent, config) {
+module.exports.CreateAmtProvisioningServer = function (parent, config) {
var obj = {};
// WSMAN stack
diff --git a/certoperations.js b/certoperations.js
index e27fae89..33e380e8 100644
--- a/certoperations.js
+++ b/certoperations.js
@@ -355,6 +355,113 @@ module.exports.CertificateOperations = function (parent) {
return AmtSetupBinStack.AmtSetupBinEncode(setupbin);
}
+
+ // Get a bare metal setup.bin file
+ obj.GetBareMetalSetupBinFile = function (amtacmactivation, oldmebxpass, newmebxpass, domain, user) {
+ // Create a setup.bin file for our own root cert
+ // Get the wiadcard certificate hash
+ var wildcardCertSha256 = null;
+ for (var i = 0; i < amtacmactivation.acmmatch.length; i++) { if (amtacmactivation.acmmatch[i].cn == '*') { wildcardCertSha256 = amtacmactivation.acmmatch[i].sha256; } }
+
+ // Create the Setup.bin stack
+ const AmtSetupBinStack = require('./amt/amt-setupbin')();
+ var setupbin = AmtSetupBinStack.AmtSetupBinCreate(3, 1); // Version 3, 1 = Records will not be consumed.
+ var certRootName = 'MeshCentral';
+
+ // Figure out what trusted FQDN to use.
+ var trustedFQDN = parent.config.settings.amtprovisioningserver.trustedfqdn
+
+ // Figure out the provisioning server port
+ var port = 9971;
+ if (typeof parent.config.settings.amtprovisioningserver.port == 'number') { port = parent.config.settings.amtprovisioningserver.port; }
+
+ // Figure out the provisioning server IP address
+ var ipaddr = '192.168.2.147'; // TODO
+ if (typeof parent.config.settings.amtprovisioningserver.ip == 'string') { ipaddr = parent.config.settings.amtprovisioningserver.ip; }
+ var ipaddrSplit = ipaddr.split('.');
+ var ipaddrStr = String.fromCharCode(parseInt(ipaddrSplit[3])) + String.fromCharCode(parseInt(ipaddrSplit[2])) + String.fromCharCode(parseInt(ipaddrSplit[1])) + String.fromCharCode(parseInt(ipaddrSplit[0]));
+
+ // Create a new record
+ var r = {};
+ r.typeIdentifier = 1;
+ r.flags = 1; // Valid, unscrambled record.
+ r.chunkCount = 0;
+ r.headerByteCount = 0;
+ r.number = 0;
+ r.variables = [];
+ setupbin.records.push(r);
+
+ // Create "Current MEBx Password" variable
+ var v = {};
+ v.moduleid = 1;
+ v.varid = 1;
+ v.length = -1;
+ v.value = oldmebxpass;
+ setupbin.records[0].variables.push(v);
+
+ // Create "New MEBx Password" variable
+ v = {};
+ v.moduleid = 1;
+ v.varid = 2;
+ v.length = -1;
+ v.value = newmebxpass;
+ setupbin.records[0].variables.push(v);
+
+ // Create "User Defined Certificate Addition" variable
+ v = {};
+ v.moduleid = 2;
+ v.varid = 8;
+ v.length = -1;
+ v.value = String.fromCharCode(2) + Buffer.from(wildcardCertSha256, 'hex').toString('binary') + String.fromCharCode(certRootName.length) + certRootName; // 2 = SHA256 hash type
+ setupbin.records[0].variables.push(v);
+
+ // Create "PKI DNS Suffix" variable
+ v = {};
+ v.moduleid = 2;
+ v.varid = 3;
+ v.length = -1;
+ v.value = trustedFQDN;
+ setupbin.records[0].variables.push(v);
+
+ // Create "Configuration Server FQDN" variable
+ v = {};
+ v.moduleid = 2;
+ v.varid = 4;
+ v.length = -1;
+ v.value = trustedFQDN;
+ setupbin.records[0].variables.push(v);
+
+ // Create "Provisioning Server Address" variable
+ v = {};
+ v.moduleid = 2;
+ v.varid = 17;
+ v.length = -1;
+ v.value = ipaddrStr;
+ setupbin.records[0].variables.push(v);
+
+ // Create "Provisioning Server Port Number" variable
+ v = {};
+ v.moduleid = 2;
+ v.varid = 18;
+ v.length = -1;
+ v.value = port;
+ setupbin.records[0].variables.push(v);
+
+ // Create "Remote Configuration Enabled (RCFG)" variable
+ v = {};
+ v.moduleid = 2;
+ v.varid = 5;
+ v.length = -1;
+ v.value = '1'; // Turn on
+ setupbin.records[0].variables.push(v);
+
+ // Write to log file
+ obj.logAmtActivation(domain, { time: new Date(), action: 'setupbin', domain: domain.id, userid: user._id, oldmebx: oldmebxpass, newmebx: newmebxpass, rootname: certRootName, hash: wildcardCertSha256, dns: 'rootcert.meshcentral.com' });
+
+ // Encode the setup.bin file
+ return AmtSetupBinStack.AmtSetupBinEncode(setupbin);
+ }
+
// Return the certificate of the remote HTTPS server
obj.loadPfxCertificate = function (filename, password) {
var r = { certs: [], keys: [] };
diff --git a/meshcentral.js b/meshcentral.js
index 6e301e20..2c94c1de 100644
--- a/meshcentral.js
+++ b/meshcentral.js
@@ -1650,8 +1650,8 @@ function CreateMeshCentralServer(config, args) {
});
// Setup Intel AMT hello server
- if ((typeof config.settings.amthelloserver == 'object') && (typeof config.settings.amthelloserver.devicegroup == 'string') && (typeof config.settings.amthelloserver.newmebxpassword == 'string') && (typeof config.settings.amthelloserver.trustedfqdn == 'string')) {
- obj.amthelloserver = require('./amthelloserver').CreateAmtHelloServer(obj, config.settings.amthelloserver);
+ if ((typeof config.settings.amtprovisioningserver == 'object') && (typeof config.settings.amtprovisioningserver.devicegroup == 'string') && (typeof config.settings.amtprovisioningserver.newmebxpassword == 'string') && (typeof config.settings.amtprovisioningserver.trustedfqdn == 'string')) {
+ obj.amtProvisioningServer = require('./amtprovisioningserver').CreateAmtProvisioningServer(obj, config.settings.amtprovisioningserver);
}
// Start collecting server stats every 5 minutes
diff --git a/meshuser.js b/meshuser.js
index cb0ea3d4..4a9d0806 100644
--- a/meshuser.js
+++ b/meshuser.js
@@ -5283,8 +5283,15 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
case 'amtsetupbin': {
if ((command.oldmebxpass != 'admin') && (common.validateString(command.oldmebxpass, 8, 16) == false)) break; // Check password
if (common.validateString(command.newmebxpass, 8, 16) == false) break; // Check password
- var bin = parent.parent.certificateOperations.GetSetupBinFile(domain.amtacmactivation, command.oldmebxpass, command.newmebxpass, domain, user);
- try { ws.send(JSON.stringify({ action: 'amtsetupbin', file: Buffer.from(bin, 'binary').toString('base64') })); } catch (ex) { }
+ if ((command.baremetal) && (parent.parent.amtProvisioningServer != null)) {
+ // Create bare metal setup.bin
+ var bin = parent.parent.certificateOperations.GetBareMetalSetupBinFile(domain.amtacmactivation, command.oldmebxpass, command.newmebxpass, domain, user);
+ try { ws.send(JSON.stringify({ action: 'amtsetupbin', file: Buffer.from(bin, 'binary').toString('base64') })); } catch (ex) { }
+ } else {
+ // Create standard setup.bin
+ var bin = parent.parent.certificateOperations.GetSetupBinFile(domain.amtacmactivation, command.oldmebxpass, command.newmebxpass, domain, user);
+ try { ws.send(JSON.stringify({ action: 'amtsetupbin', file: Buffer.from(bin, 'binary').toString('base64') })); } catch (ex) { }
+ }
break;
}
case 'meshToolInfo': {
diff --git a/public/scripts/agent-redir-ws-0.1.1.js b/public/scripts/agent-redir-ws-0.1.1.js
index 49687239..26c45322 100644
--- a/public/scripts/agent-redir-ws-0.1.1.js
+++ b/public/scripts/agent-redir-ws-0.1.1.js
@@ -172,11 +172,11 @@ var CreateAgentRedirect = function (meshserver, module, serverPublicNamePort, au
if (typeof e.data == 'string') {
obj.xxOnControlCommand(e.data);
} else {
- // If only 1 byte
- if ((cmdAccLen == 0) && (e.data.byteLength == 1)) return; // Ignore single byte data, this is a keep alive.
-
// Send the data to the module
if (obj.m.ProcessBinaryCommand) {
+ // If only 1 byte
+ if ((cmdAccLen == 0) && (e.data.byteLength < 4)) return; // Ignore any commands less than 4 bytes.
+
// Send as Binary Command
if (cmdAccLen != 0) {
// Accumulator is active
diff --git a/views/default.handlebars b/views/default.handlebars
index 2ca95879..f6542f43 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -4267,7 +4267,8 @@
x += addHtmlValue("Old Password", '');
x += addHtmlValue("New Password*", '');
x += addHtmlValue("New Password*", '');
- x += ' ' + "* 8 characters, 1 upper, 1 lower, 1 numeric, 1 non-alpha numeric." + '';
+ if (features2 & 0x00000020) { x += ''; } // Intel AMT LAN provisioning server is active.
+ x += '
' + "* 8 characters, 1 upper, 1 lower, 1 numeric, 1 non-alpha numeric." + '
';
setDialogMode(2, "Intel® AMT ACM", 3, showAmtAcmSetupEx, x);
Q('dp1password0').focus();
validateAmtAcmSetupEx();
@@ -4281,7 +4282,7 @@
}
function showAmtAcmSetupEx() {
- meshserver.send({ action: 'amtsetupbin', oldmebxpass: Q('dp1password0').value, newmebxpass: Q('dp1password1').value });
+ meshserver.send({ action: 'amtsetupbin', oldmebxpass: Q('dp1password0').value, newmebxpass: Q('dp1password1').value, baremetal: ((features2 & 0x00000020) && (Q('dp1lanprov').checked)) });
}
// Display the Intel AMT scanning dialog box
diff --git a/webserver.js b/webserver.js
index b931cd42..e01adf3f 100644
--- a/webserver.js
+++ b/webserver.js
@@ -2476,6 +2476,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((obj.parent.firebase != null) && (obj.parent.firebase.pushOnly != true)) { features2 += 0x00000004; } // Indicates the server supports Firebase two-way push messaging
if (obj.parent.webpush != null) { features2 += 0x00000008; } // Indicates web push is enabled
if (((obj.args.noagentupdate == 1) || (obj.args.noagentupdate == true))) { features2 += 0x00000010; } // No agent update
+ if (parent.amtProvisioningServer != null) { features2 += 0x00000020; } // Intel AMT LAN provisioning server
// Create a authentication cookie
const authCookie = obj.parent.encodeCookie({ userid: dbGetFunc.user._id, domainid: domain.id, ip: req.clientIp }, obj.parent.loginCookieEncryptionKey);