From 9fe71f88421d4174507220e4cf1f9668a0d36d93 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Fri, 21 Jun 2019 17:18:48 -0700 Subject: [PATCH] New Intel AMT ACM activation with MeshCMD --- agents/MeshCmd-signed.exe | Bin 5778440 -> 5775920 bytes agents/MeshCmd64-signed.exe | Bin 5361160 -> 5358640 bytes agents/meshcmd.js | 263 +++++++++++++++--------------------- agents/meshcmd.min.js | 263 +++++++++++++++--------------------- certoperations.js | 20 +-- meshagent.js | 4 +- views/default.handlebars | 12 +- webserver.js | 86 ++++++++++++ 8 files changed, 324 insertions(+), 324 deletions(-) diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 2d7f353889621470ec177bd9601eba53ab276bb4..3e0703843088698f8e36aea0ead9a6a8c58d9066 100644 GIT binary patch delta 11616 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 P#j=;bD;}COY101z?QL$8 delta 12469 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 delta 12393 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 diff --git a/agents/meshcmd.js b/agents/meshcmd.js index 45485f59..9e607fa7 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -498,9 +498,10 @@ function run(argv) { activeToCCM(); } else if (settings.action == 'amtacm') { // Start activation to ACM - if ((settings.wss == null) || (typeof settings.wss != 'string') || (settings.wss == '')) { console.log('No or invalid \"server name\" specified, use --wss [servername:port].'); exit(1); return; } - if ((settings.profile == null) || (typeof settings.profile != 'string') || (settings.profile == '')) { console.log('No or invalid \"profile name\" specified, use --profile [name].'); exit(1); return; } - settings.protocol = 'http:'; + if ((settings.wss == null) || (typeof settings.wss != 'string') || (settings.wss == '')) { console.log('No server URL specified, use --wss [url].'); exit(1); return; } + //if ((settings.profile == null) || (typeof settings.profile != 'string') || (settings.profile == '')) { console.log('No or invalid \"profile name\" specified, use --profile [name].'); exit(1); return; } + if ((typeof settings.profile != 'string') || (settings.profile == '')) { settings.profile = null; } + //settings.protocol = 'http:'; settings.localport = 16992; debug(1, "Settings: " + JSON.stringify(settings)); activeToACM(); @@ -848,24 +849,63 @@ function deactivateACMEx() { }); } +// +// Get Intel AMT activation hashes +// + +var trustedHashes = null; +function getTrustedHashes(amtMei, func, tag) { + console.log('getTrustedHashes'); + if (trustedHashes != null) { func(tag); } + trustedHashes = []; + amtMei.getHashHandles(function (handles) { + var exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + this.getCertHashEntry(handles[i], function (result) { + if (result.isActive == 1) { trustedHashes.push(result.certificateHash.toLowerCase()); } + if (--exitOnCount == 0) { func(tag); } + }); + } + }); +} // // Activate Intel AMT to ACM // function activeToACM() { - // See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack - console.log('Starting AMT Provisioning to Admin Control Mode.'); + console.log('Starting Intel AMT provisioning to Admin Control Mode (ACM) attempt...'); settings.noconsole = true; + // Display Intel AMT version and activation state mestate = {}; var amtMeiModule, amtMei; try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); - amtMei.getProvisioningState(function (result) { - if (result) { - mestate.ProvisioningState = result; - startLms(getFwNonce); // TODO: Fix this so that it works even if LMS already running. + amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } }); + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } }); + amtMei.getDnsSuffix(function (result) { + if (mestate.ProvisioningState.state !== 0) { console.log("Intel AMT is not in pre-provisioning state: " + mestate.ProvisioningState.stateStr); exit(100); return; } + if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; } + var fqdn = null; + if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } + if (result) { fqdn = result; } // If Intel AMT has a trusted DNS suffix set, use that one. + else { + // Look for the DNS suffix for the Intel AMT Ethernet interface + var interfaces = require('os').networkInterfaces(); + for (var i in interfaces) { + for (var j in interfaces[i]) { + if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; } + } + } + } + if (fqdn != null) { + settings.fqdn = fqdn; + settings.uuid = mestate.uuid; + getTrustedHashes(amtMei, function () { startLms(getFwNonce, amtMei); }); + } else { + console.log("Trusted DNS suffix not set, can't perform ACM activation."); exit(100); return; } }); } @@ -873,164 +913,81 @@ function activeToACM() { // Gets the FWNonce from AMT and saves it to a file. function getFwNonce() { osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) { + if (status != 200) { console.log("Unable to get firmware activation nonce, status=" + status); exit(100); return; } var fwNonce = responses['IPS_HostBasedSetupService'].response['ConfigurationNonce']; var digestRealm = responses['AMT_GeneralSettings'].response['DigestRealm']; - var amtMeiModule, amtMei, str; - try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } - amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); - amtMei.getDnsSuffix(function (result) { - var fqdn = null; - if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } - if (result) { fqdn = result; } // If Intel AMT has a trusted DNS suffix set, use that one. - else { - // Look for the DNS suffix for the Intel AMT Ethernet interface - var interfaces = require('os').networkInterfaces(); - for (var i in interfaces) { - for (var j in interfaces[i]) { - if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; } - } - } - } - if (fqdn != null) { - activeToACMEx(fwNonce, fqdn, digestRealm); - } else { - console.log("Trusted DNS suffix not set, can't perform ACM activation."); exit(100); return; - } - }); + activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid); }); } -// Sends a message to RCS server using RCS Message Protocol -function sendRCSMessage(socket, status, event, message) { - //console.log('Status: ' + status + '. Event: ' + event + '. Message: ' + message); - if (socket !== null) { socket.write({ "status": status, "event": event, "data": message }); } -} +// Connect to the activation server and perform ACM activation +function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { + console.log('FQDN: ' + dnsSuffix); + console.log('UUID: ' + uuid); + console.log('Realm: ' + digestRealm); + console.log('Nonce: ' + fwNonce); + console.log('Connecting to ' + settings.wss); -function activeToACMEx(fwNonce, dnsSuffix, digestRealm) { - // open connection to RCS - console.log('Initializing WebSocket...'); - // Establish WebSocket connection to RCS server - var connection = http.request(settings.wss); + // Establish WebSocket connection to activation server + var options = http.parseUri(settings.wss); + options.checkServerIdentity = function (clientName, certs) { }; // TODO + options.rejectUnauthorized = false; + var connection = http.request(options); connection.on('upgrade', function (response, socket) { - // WebSocket is up. Handle data on the duplex socket + console.log('Connected, requesting activation...'); + socket.on('end', function () { console.log('Connection closed'); exit(0); }); + socket.on('error', function () { console.log('Connection error'); exit(100); }); socket.on('data', function (data) { - // All messages from RCS are JSON.stringify format and need to be parsed - var message = JSON.parse(data); - // Check RCS Message Protocol version. Exit if version not supported - if (message.version > RCSMessageProtocolVersion) { console.log('Unsupported RCS server.'); socket.end(); exit(0) } - // Handle the AMT provisioning certificate blob (contains provisioning certificate, mcnonce, digital signature and password hash) - if (message.data.provCertObj !== undefined) { - activeToACMEx1(message.data, function (stack, name, responses, status, message) { - if (status !== 200) { - if (status == 2) { - console.log('AMT already provisioned.Exiting ' + status); - sendRCSMessage(socket, "error", "finish", "failed with status: " + status); - } else { - console.log('Failed to fetch activation status, status ' + status); - sendRCSMessage(socket, "error", "finish", "failed with status: " + status); - } - socket.end(); - exit(status); - } else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { - console.log('Admin control mode activation not allowed'); - sendRCSMessage(socket, "error", "finish", "failed with message: Admin control mode activation not allowed"); - socket.end(); - exit(status); + // Parse and check the response + var cmd = null; + try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; } + if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; } + if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; } + if (cmd.action != 'acmactivate') { console.log('Invalid server response, command: ' + cmd.cmd); exit(100); return; } + if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; } + if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } + if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; } + if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; } + + // We are ready to go, perform activation. + cmd.index = 0; + performAcmActivation(cmd, function (result) { + if (result == false) { + console.log('Intel AMT ACM activation failed.'); + } else { + if ((cmd.profileScript !== null) && (cmd.rawpassword != null)) { + console.log("Intel AMT ACM activation success, applying profile..."); + settings.scriptjson = cmd.profileScript; + settings.password = cmd.rawpassword; // TODO: This is only going to work if the server sends the raw password?? + settings.username = 'admin'; + startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); } else { - activeToACMEx2(message, function (stack, name, responses, status, message) { - if (status != 200) { - console.log('Failed to activate, status ' + status); - sendRCSMessage(socket, "error", "finish", "failed to activate. Status: " + status); - } else if (responses.Body.ReturnValue != 0) { - console.log('Admin control mode activation failed: ' + responses.Body.ReturnValueStr); - sendRCSMessage(socket, "error", "finish", "failed to activate: " + responses.Body.ReturnValueStr); - } else { - if (message.profileScript !== null) { - console.log("Running MEScript..."); - settings.scriptjson = message.profileScript; - settings.password = message.amtPassword - settings.username = 'admin'; - startMeScriptEx(function () { - console.log('AMT Profile applied'); - sendRCSMessage(socket, "ok", "finish", "success"); - socket.end(); - exit(0); - }, stack); - } else { - sendRCSMessage(socket, "ok", "finish", "success"); - socket.end(); - exit(0); - } - console.log('AMT Provisioning Success'); - } - //socket.end(); - //exit(status); - }); + console.log('Intel AMT ACM activation success.'); + socket.end(); + exit(0); } - }); - } - if (message.event.toString() == "cmd" && message.data.toString() == "acmready") { - sendRCSMessage(socket, "ok", "message", JSON.stringify(fwNonce)); - } - }); - socket.on('end', function () { console.log('WebSocket closed'); }); - sendRCSMessage(socket, "ok", "cmd", { "cmd": "acm", "dnssuffix": dnsSuffix, "profile": settings.profile, 'digestrealm': digestRealm, 'fwnonce': fwNonce }); - }); -} - -// Detects AMT provisioning state and injects the certificate chain into AMT firmware -function activeToACMEx1(data, callback) { - if (mestate.ProvisioningState.state == 0) { - console.log('Performing ACM provisioning...'); - // Perform full provisioning -- AMT was fully unprovisioned - injectCert(0, data, function (stack, name, responses, status, data) { - if (status !== 200) { exit(status); return; } - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; } - else if (responses['Body']['ReturnValue'] == 0) { - osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) { - callback(stack, name, responses, status, data); - }); - } - }); - } else if (mestate.ProvisioningState.state == 1) { - // Perform partial provisioning -- AMT was partial unprovisioned - // Currently not functional due to limitations in the HW. - console.log('Partial provisioning flow currently not available.'); - exit(0); - //osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToACMEx2); - } else { - // AMT already provisioned - callback(null, null, null, 2, 'AMT already provisioned. Exiting') - exit(0); - } -} - -// Recursive function to inject the provisioning certificates into AMT in the proper order -function injectCert(index, cert, callback, stack, name, responses, status) { - var leaf = false; - var root = false; - if (index == 0) { leaf = true; } - if (index == cert.provCertObj.certChain.length - 1) { root = true; } - if (index < cert.provCertObj.certChain.length) { - if (cert.provCertObj.certChain[index] !== undefined) { - osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(cert.provCertObj.certChain[index], leaf, root, function (stack, name, responses, status) { - if (status !== 200) { exit(status); return; } - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; } - else if (responses['Body']['ReturnValue'] == 0) { - index++; - injectCert(index, cert, callback, stack, name, responses, status); } }); - } - } else { callback(stack, name, responses, status, cert); } + }); + socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate', fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes }); + }); + connection.end(); } -// Sends the password hash, mcnonce, and digital signature to complete the admin control mode provisioning -function activeToACMEx2(data, callback) { - //var passwordhash = md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + data.passwordHash).substring(0, 32); - //var debugreturn = {"Body": {"ReturnValue": 0}}; - //console.log("DEBUG: Everything up to activation works"); callback(null, null, debugreturn, 200, data); - osamtstack.IPS_HostBasedSetupService_AdminSetup(2, data.passwordHash, data.mcNonce, 2, data.digitalSignature, function (stack, name, responses, status) { callback(stack, name, responses, status, data); }); +// Recursive function to inject the provisioning certificates into AMT in the proper order and completes ACM activation +function performAcmActivation(acmdata, func) { + var leaf = (acmdata.index == 0), root = (acmdata.index == (acmdata.certs.length - 1)); + if ((acmdata.index < acmdata.certs.length) && (acmdata.certs[acmdata.index] != null)) { + osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(acmdata.certs[acmdata.index], leaf, root, function (stack, name, responses, status) { + if (status !== 200) { debug('AddNextCertInChain status=' + status); return; } + else if (responses['Body']['ReturnValue'] !== 0) { debug('AddNextCertInChain error=' + responses['Body']['ReturnValue']); return; } + else { acmdata.index++; performAcmActivation(acmdata, func); } + }); + } else { + osamtstack.IPS_HostBasedSetupService_AdminSetup(2, acmdata.password, acmdata.nonce, 2, acmdata.signature, + function (stack, name, responses, status) { func((status == 200) && (responses['Body']['ReturnValue'] == 0)); } + ); + } } // diff --git a/agents/meshcmd.min.js b/agents/meshcmd.min.js index 45485f59..9e607fa7 100644 --- a/agents/meshcmd.min.js +++ b/agents/meshcmd.min.js @@ -498,9 +498,10 @@ function run(argv) { activeToCCM(); } else if (settings.action == 'amtacm') { // Start activation to ACM - if ((settings.wss == null) || (typeof settings.wss != 'string') || (settings.wss == '')) { console.log('No or invalid \"server name\" specified, use --wss [servername:port].'); exit(1); return; } - if ((settings.profile == null) || (typeof settings.profile != 'string') || (settings.profile == '')) { console.log('No or invalid \"profile name\" specified, use --profile [name].'); exit(1); return; } - settings.protocol = 'http:'; + if ((settings.wss == null) || (typeof settings.wss != 'string') || (settings.wss == '')) { console.log('No server URL specified, use --wss [url].'); exit(1); return; } + //if ((settings.profile == null) || (typeof settings.profile != 'string') || (settings.profile == '')) { console.log('No or invalid \"profile name\" specified, use --profile [name].'); exit(1); return; } + if ((typeof settings.profile != 'string') || (settings.profile == '')) { settings.profile = null; } + //settings.protocol = 'http:'; settings.localport = 16992; debug(1, "Settings: " + JSON.stringify(settings)); activeToACM(); @@ -848,24 +849,63 @@ function deactivateACMEx() { }); } +// +// Get Intel AMT activation hashes +// + +var trustedHashes = null; +function getTrustedHashes(amtMei, func, tag) { + console.log('getTrustedHashes'); + if (trustedHashes != null) { func(tag); } + trustedHashes = []; + amtMei.getHashHandles(function (handles) { + var exitOnCount = handles.length; + for (var i = 0; i < handles.length; ++i) { + this.getCertHashEntry(handles[i], function (result) { + if (result.isActive == 1) { trustedHashes.push(result.certificateHash.toLowerCase()); } + if (--exitOnCount == 0) { func(tag); } + }); + } + }); +} // // Activate Intel AMT to ACM // function activeToACM() { - // See if MicroLMS needs to be started and setup the $$OsAdmin wsman stack - console.log('Starting AMT Provisioning to Admin Control Mode.'); + console.log('Starting Intel AMT provisioning to Admin Control Mode (ACM) attempt...'); settings.noconsole = true; + // Display Intel AMT version and activation state mestate = {}; var amtMeiModule, amtMei; try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; }); - amtMei.getProvisioningState(function (result) { - if (result) { - mestate.ProvisioningState = result; - startLms(getFwNonce); // TODO: Fix this so that it works even if LMS already running. + amtMei.getProvisioningState(function (result) { if (result) { mestate.ProvisioningState = result; } }); + amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); + amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } }); + amtMei.getDnsSuffix(function (result) { + if (mestate.ProvisioningState.state !== 0) { console.log("Intel AMT is not in pre-provisioning state: " + mestate.ProvisioningState.stateStr); exit(100); return; } + if (mestate.uuid == null) { console.log("Unable to get Intel AMT UUID."); exit(100); return; } + var fqdn = null; + if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } + if (result) { fqdn = result; } // If Intel AMT has a trusted DNS suffix set, use that one. + else { + // Look for the DNS suffix for the Intel AMT Ethernet interface + var interfaces = require('os').networkInterfaces(); + for (var i in interfaces) { + for (var j in interfaces[i]) { + if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; } + } + } + } + if (fqdn != null) { + settings.fqdn = fqdn; + settings.uuid = mestate.uuid; + getTrustedHashes(amtMei, function () { startLms(getFwNonce, amtMei); }); + } else { + console.log("Trusted DNS suffix not set, can't perform ACM activation."); exit(100); return; } }); } @@ -873,164 +913,81 @@ function activeToACM() { // Gets the FWNonce from AMT and saves it to a file. function getFwNonce() { osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) { + if (status != 200) { console.log("Unable to get firmware activation nonce, status=" + status); exit(100); return; } var fwNonce = responses['IPS_HostBasedSetupService'].response['ConfigurationNonce']; var digestRealm = responses['AMT_GeneralSettings'].response['DigestRealm']; - var amtMeiModule, amtMei, str; - try { amtMeiModule = require('amt-mei'); amtMei = new amtMeiModule(); } catch (ex) { console.log(ex); exit(1); return; } - amtMei.getLanInterfaceSettings(0, function (result) { if (result) { mestate.net0 = result; } }); - amtMei.getDnsSuffix(function (result) { - var fqdn = null; - if ((mestate.net0 == null) && (meinfo.net0.enabled != 0)) { console.log("No Intel AMT wired interface, can't perform ACM activation."); exit(100); return; } - if (result) { fqdn = result; } // If Intel AMT has a trusted DNS suffix set, use that one. - else { - // Look for the DNS suffix for the Intel AMT Ethernet interface - var interfaces = require('os').networkInterfaces(); - for (var i in interfaces) { - for (var j in interfaces[i]) { - if ((interfaces[i][j].mac == mestate.net0.mac) && (interfaces[i][j].fqdn != null) && (interfaces[i][j].fqdn != '')) { fqdn = interfaces[i][j].fqdn; } - } - } - } - if (fqdn != null) { - activeToACMEx(fwNonce, fqdn, digestRealm); - } else { - console.log("Trusted DNS suffix not set, can't perform ACM activation."); exit(100); return; - } - }); + activeToACMEx(fwNonce, settings.fqdn, digestRealm, settings.uuid); }); } -// Sends a message to RCS server using RCS Message Protocol -function sendRCSMessage(socket, status, event, message) { - //console.log('Status: ' + status + '. Event: ' + event + '. Message: ' + message); - if (socket !== null) { socket.write({ "status": status, "event": event, "data": message }); } -} +// Connect to the activation server and perform ACM activation +function activeToACMEx(fwNonce, dnsSuffix, digestRealm, uuid) { + console.log('FQDN: ' + dnsSuffix); + console.log('UUID: ' + uuid); + console.log('Realm: ' + digestRealm); + console.log('Nonce: ' + fwNonce); + console.log('Connecting to ' + settings.wss); -function activeToACMEx(fwNonce, dnsSuffix, digestRealm) { - // open connection to RCS - console.log('Initializing WebSocket...'); - // Establish WebSocket connection to RCS server - var connection = http.request(settings.wss); + // Establish WebSocket connection to activation server + var options = http.parseUri(settings.wss); + options.checkServerIdentity = function (clientName, certs) { }; // TODO + options.rejectUnauthorized = false; + var connection = http.request(options); connection.on('upgrade', function (response, socket) { - // WebSocket is up. Handle data on the duplex socket + console.log('Connected, requesting activation...'); + socket.on('end', function () { console.log('Connection closed'); exit(0); }); + socket.on('error', function () { console.log('Connection error'); exit(100); }); socket.on('data', function (data) { - // All messages from RCS are JSON.stringify format and need to be parsed - var message = JSON.parse(data); - // Check RCS Message Protocol version. Exit if version not supported - if (message.version > RCSMessageProtocolVersion) { console.log('Unsupported RCS server.'); socket.end(); exit(0) } - // Handle the AMT provisioning certificate blob (contains provisioning certificate, mcnonce, digital signature and password hash) - if (message.data.provCertObj !== undefined) { - activeToACMEx1(message.data, function (stack, name, responses, status, message) { - if (status !== 200) { - if (status == 2) { - console.log('AMT already provisioned.Exiting ' + status); - sendRCSMessage(socket, "error", "finish", "failed with status: " + status); - } else { - console.log('Failed to fetch activation status, status ' + status); - sendRCSMessage(socket, "error", "finish", "failed with status: " + status); - } - socket.end(); - exit(status); - } else if (responses['IPS_HostBasedSetupService'].response['AllowedControlModes'].length != 2) { - console.log('Admin control mode activation not allowed'); - sendRCSMessage(socket, "error", "finish", "failed with message: Admin control mode activation not allowed"); - socket.end(); - exit(status); + // Parse and check the response + var cmd = null; + try { cmd = JSON.parse(data); } catch (ex) { console.log('Unable to parse server response: ' + data); exit(100); return; } + if (typeof cmd != 'object') { console.log('Invalid server response: ' + cmd); exit(100); return; } + if (typeof cmd.errorText == 'string') { console.log('Server error: ' + cmd.errorText); exit(100); return; } + if (cmd.action != 'acmactivate') { console.log('Invalid server response, command: ' + cmd.cmd); exit(100); return; } + if (typeof cmd.signature != 'string') { console.log('Invalid server signature'); exit(100); return; } + if (typeof cmd.password != 'string') { console.log('Invalid server password'); exit(100); return; } + if (typeof cmd.nonce != 'string') { console.log('Invalid server nonce'); exit(100); return; } + if (typeof cmd.certs != 'object') { console.log('Invalid server certificates'); exit(100); return; } + + // We are ready to go, perform activation. + cmd.index = 0; + performAcmActivation(cmd, function (result) { + if (result == false) { + console.log('Intel AMT ACM activation failed.'); + } else { + if ((cmd.profileScript !== null) && (cmd.rawpassword != null)) { + console.log("Intel AMT ACM activation success, applying profile..."); + settings.scriptjson = cmd.profileScript; + settings.password = cmd.rawpassword; // TODO: This is only going to work if the server sends the raw password?? + settings.username = 'admin'; + startMeScriptEx(function () { console.log('Intel AMT profile applied.'); socket.end(); exit(0); }, stack); } else { - activeToACMEx2(message, function (stack, name, responses, status, message) { - if (status != 200) { - console.log('Failed to activate, status ' + status); - sendRCSMessage(socket, "error", "finish", "failed to activate. Status: " + status); - } else if (responses.Body.ReturnValue != 0) { - console.log('Admin control mode activation failed: ' + responses.Body.ReturnValueStr); - sendRCSMessage(socket, "error", "finish", "failed to activate: " + responses.Body.ReturnValueStr); - } else { - if (message.profileScript !== null) { - console.log("Running MEScript..."); - settings.scriptjson = message.profileScript; - settings.password = message.amtPassword - settings.username = 'admin'; - startMeScriptEx(function () { - console.log('AMT Profile applied'); - sendRCSMessage(socket, "ok", "finish", "success"); - socket.end(); - exit(0); - }, stack); - } else { - sendRCSMessage(socket, "ok", "finish", "success"); - socket.end(); - exit(0); - } - console.log('AMT Provisioning Success'); - } - //socket.end(); - //exit(status); - }); + console.log('Intel AMT ACM activation success.'); + socket.end(); + exit(0); } - }); - } - if (message.event.toString() == "cmd" && message.data.toString() == "acmready") { - sendRCSMessage(socket, "ok", "message", JSON.stringify(fwNonce)); - } - }); - socket.on('end', function () { console.log('WebSocket closed'); }); - sendRCSMessage(socket, "ok", "cmd", { "cmd": "acm", "dnssuffix": dnsSuffix, "profile": settings.profile, 'digestrealm': digestRealm, 'fwnonce': fwNonce }); - }); -} - -// Detects AMT provisioning state and injects the certificate chain into AMT firmware -function activeToACMEx1(data, callback) { - if (mestate.ProvisioningState.state == 0) { - console.log('Performing ACM provisioning...'); - // Perform full provisioning -- AMT was fully unprovisioned - injectCert(0, data, function (stack, name, responses, status, data) { - if (status !== 200) { exit(status); return; } - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; } - else if (responses['Body']['ReturnValue'] == 0) { - osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], function (stack, name, responses, status) { - callback(stack, name, responses, status, data); - }); - } - }); - } else if (mestate.ProvisioningState.state == 1) { - // Perform partial provisioning -- AMT was partial unprovisioned - // Currently not functional due to limitations in the HW. - console.log('Partial provisioning flow currently not available.'); - exit(0); - //osamtstack.BatchEnum(null, ['*AMT_GeneralSettings', '*IPS_HostBasedSetupService'], activeToACMEx2); - } else { - // AMT already provisioned - callback(null, null, null, 2, 'AMT already provisioned. Exiting') - exit(0); - } -} - -// Recursive function to inject the provisioning certificates into AMT in the proper order -function injectCert(index, cert, callback, stack, name, responses, status) { - var leaf = false; - var root = false; - if (index == 0) { leaf = true; } - if (index == cert.provCertObj.certChain.length - 1) { root = true; } - if (index < cert.provCertObj.certChain.length) { - if (cert.provCertObj.certChain[index] !== undefined) { - osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(cert.provCertObj.certChain[index], leaf, root, function (stack, name, responses, status) { - if (status !== 200) { exit(status); return; } - else if (responses['Body']['ReturnValue'] !== 0) { exit(responses['Body']['ReturnValueStr']); return; } - else if (responses['Body']['ReturnValue'] == 0) { - index++; - injectCert(index, cert, callback, stack, name, responses, status); } }); - } - } else { callback(stack, name, responses, status, cert); } + }); + socket.write({ client: 'meshcmd', version: 1, action: 'acmactivate', fqdn: dnsSuffix, realm: digestRealm, nonce: fwNonce, uuid: uuid, profile: settings.profile, hashes: trustedHashes }); + }); + connection.end(); } -// Sends the password hash, mcnonce, and digital signature to complete the admin control mode provisioning -function activeToACMEx2(data, callback) { - //var passwordhash = md5hex('admin:' + responses['AMT_GeneralSettings'].response['DigestRealm'] + ':' + data.passwordHash).substring(0, 32); - //var debugreturn = {"Body": {"ReturnValue": 0}}; - //console.log("DEBUG: Everything up to activation works"); callback(null, null, debugreturn, 200, data); - osamtstack.IPS_HostBasedSetupService_AdminSetup(2, data.passwordHash, data.mcNonce, 2, data.digitalSignature, function (stack, name, responses, status) { callback(stack, name, responses, status, data); }); +// Recursive function to inject the provisioning certificates into AMT in the proper order and completes ACM activation +function performAcmActivation(acmdata, func) { + var leaf = (acmdata.index == 0), root = (acmdata.index == (acmdata.certs.length - 1)); + if ((acmdata.index < acmdata.certs.length) && (acmdata.certs[acmdata.index] != null)) { + osamtstack.IPS_HostBasedSetupService_AddNextCertInChain(acmdata.certs[acmdata.index], leaf, root, function (stack, name, responses, status) { + if (status !== 200) { debug('AddNextCertInChain status=' + status); return; } + else if (responses['Body']['ReturnValue'] !== 0) { debug('AddNextCertInChain error=' + responses['Body']['ReturnValue']); return; } + else { acmdata.index++; performAcmActivation(acmdata, func); } + }); + } else { + osamtstack.IPS_HostBasedSetupService_AdminSetup(2, acmdata.password, acmdata.nonce, 2, acmdata.signature, + function (stack, name, responses, status) { func((status == 200) && (responses['Body']['ReturnValue'] == 0)); } + ); + } } // diff --git a/certoperations.js b/certoperations.js index ef38101a..123f21e6 100644 --- a/certoperations.js +++ b/certoperations.js @@ -30,12 +30,12 @@ module.exports.CertificateOperations = function (parent) { // Sign a Intel AMT ACM activation request obj.signAcmRequest = function (domain, request, user, pass, ipport, nodeid, meshid, computerName, agentId) { - if ((domain == null) || (domain.amtacmactivation == null) || (domain.amtacmactivation.certs == null) || (request == null) || (request.nonce == null) || (request.realm == null) || (request.fqdn == null) || (request.hash == null)) return null; - if (parent.common.validateString(request.nonce, 16, 256) == false) return null; - if (parent.common.validateString(request.realm, 16, 256) == false) return null; - if (parent.common.validateString(request.fqdn, 4, 256) == false) return null; - if (parent.common.validateString(request.hash, 16, 256) == false) return null; - if (parent.common.validateString(request.uuid, 36, 36) == false) return null; + if ((domain == null) || (domain.amtacmactivation == null) || (domain.amtacmactivation.certs == null) || (request == null) || (request.nonce == null) || (request.realm == null) || (request.fqdn == null) || (request.hash == null)) return { 'action': 'acmactivate', 'error': 1, 'errorText': 'Invalid arguments' }; + if (parent.common.validateString(request.nonce, 16, 256) == false) return { 'action': 'acmactivate', 'error': 1, 'errorText': 'Invalid nonce argument' }; + if (parent.common.validateString(request.realm, 16, 256) == false) return { 'action': 'acmactivate', 'error': 1, 'errorText': 'Invalid realm argument' }; + if (parent.common.validateString(request.fqdn, 4, 256) == false) return { 'action': 'acmactivate', 'error': 1, 'errorText': 'Invalid FQDN argument' }; + if (parent.common.validateString(request.hash, 16, 256) == false) return { 'action': 'acmactivate', 'error': 1, 'errorText': 'Invalid hash argument' }; + if (parent.common.validateString(request.uuid, 36, 36) == false) return { 'action': 'acmactivate', 'error': 1, 'errorText': 'Invalid UUID argument' }; // Look for the signing certificate var signkey = null, certChain = null, hashAlgo = null, certIndex = null; @@ -44,10 +44,10 @@ module.exports.CertificateOperations = function (parent) { if ((certEntry.sha256 == request.hash) && ((certEntry.cn == '*') || (certEntry.cn == request.fqdn))) { hashAlgo = 'sha256'; signkey = certEntry.key; certChain = certEntry.certs; certIndex = i; break; } if ((certEntry.sha1 == request.hash) && ((certEntry.cn == '*') || (certEntry.cn == request.fqdn))) { hashAlgo = 'sha1'; signkey = certEntry.key; certChain = certEntry.certs; certIndex = i; break; } } - if (signkey == null) return null; // Did not find a match. + if (signkey == null) return { 'action': 'acmactivate', 'error': 2, 'errorText': 'No signing certificate found' }; // Did not find a match. // If the matching certificate is a root cert, issue a leaf cert that matches the fqdn - if (domain.amtacmactivation.certs[certIndex].cn == '*') return; // TODO: Add support for this mode + if (domain.amtacmactivation.certs[certIndex].cn == '*') return { 'action': 'acmactivate', 'error': 3, 'errorText': 'Unsupported activation' }; // TODO: Add support for this mode // Setup both nonces, ready to be signed const mcNonce = Buffer.from(obj.crypto.randomBytes(20), 'binary'); @@ -59,10 +59,10 @@ module.exports.CertificateOperations = function (parent) { var signer = obj.crypto.createSign(hashAlgo); signer.update(Buffer.concat([fwNonce, mcNonce])); signature = signer.sign(signkey, 'base64'); - } catch (ex) { return null; } + } catch (ex) { return { 'action': 'acmactivate', 'error': 4, 'errorText': 'Unable to perform signature' }; } // Log the activation request, logging is a required step for activation. - if (obj.logAmtActivation(domain, { time: new Date(), domain: domain.id, amtUuid: request.uuid, certHash: request.hash, hashType: hashAlgo, amtRealm: request.realm, amtFqdn: request.fqdn, user: user, password: pass, ipport: ipport, nodeid: nodeid, meshid: meshid, computerName: computerName, agentId: agentId }) == false) return null; + if (obj.logAmtActivation(domain, { time: new Date(), domain: domain.id, amtUuid: request.uuid, certHash: request.hash, hashType: hashAlgo, amtRealm: request.realm, amtFqdn: request.fqdn, user: user, password: pass, ipport: ipport, nodeid: nodeid, meshid: meshid, computerName: computerName, agentId: agentId }) == false) return { 'action': 'acmactivate', 'error': 5, 'errorText': 'Unable to log operation' }; // Return the signature with the computed account password hash return { 'action': 'acmactivate', 'signature': signature, 'password': obj.crypto.createHash('md5').update(user + ':' + request.realm + ':' + pass).digest('hex'), 'nonce': mcNonce.toString('base64'), 'certs': certChain }; diff --git a/meshagent.js b/meshagent.js index 7295baab..5161295c 100644 --- a/meshagent.js +++ b/meshagent.js @@ -1222,7 +1222,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { // Agent is asking the server to sign an Intel AMT ACM activation request var signResponse = parent.parent.certificateOperations.signAcmRequest(domain, command, 'admin', amtpassword, obj.remoteaddrport, obj.dbNodeKey, obj.dbMeshKey, obj.agentInfo.computerName, obj.agentInfo.agentId); // TODO: Place account credentials!!! - if (signResponse != null) { + if ((signResponse != null) && (signResponse.error == null)) { // Log this activation event var event = { etype: 'node', action: 'amtactivate', nodeid: obj.dbNodeKey, domain: domain.id, msg: 'Device requested Intel AMT ACM activation, FQDN: ' + command.fqdn, ip: obj.remoteaddrport }; if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the node. Another event will come. @@ -1232,7 +1232,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) { ChangeAgentCoreInfo({ "intelamt": { user: 'admin', pass: amtpassword, uuid: command.uuid, realm: command.realm } }); // Send the activation response - obj.send(JSON.stringify(signResponse)); + //obj.send(JSON.stringify(signResponse)); // DEBUG**************************** } break; } diff --git a/views/default.handlebars b/views/default.handlebars index 152ba3e5..e5f1c76e 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -2766,8 +2766,8 @@ // Windows agent install //x += "
To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and configuration file and install the agent on the computer to manage.

"; x += "
To add a new computer to device group \"" + EscapeHtml(mesh.name) + "\", download the mesh agent and install it the computer to manage. This agent has server and device group information embedded within it.

"; - x += addHtmlValue('Mesh Agent', 'Windows (.exe)'); - x += addHtmlValue('Mesh Agent', 'Windows x64 (.exe)'); + x += addHtmlValue('Mesh Agent', 'Windows (.exe)'); + x += addHtmlValue('Mesh Agent', 'Windows x64 (.exe)'); if (debugmode > 0) { x += addHtmlValue('Settings File', '' + EscapeHtml(mesh.name) + ' settings (.msh)'); } x += "
"; @@ -2783,8 +2783,8 @@ // Windows agent uninstall x += ""; // Linux agent uninstall @@ -4106,7 +4106,7 @@ ++count; date = new Date(date.getTime() - (1000 * 60 * 60 * 24)); // Substract one day } - QH('p10html2', '' + x + '
Day7 Day Power State
'); + QH('p10html2', '' + x + '
Day7 Day Power State
'); } // Return a color for the given power state @@ -4261,7 +4261,7 @@ function p10showMeshRouterDialog() { if (xxdialogMode) return; var x = "
MeshCentral Router is a Windows tool for TCP port mapping. You can, for example, RDP into a remote device thru this server.

"; - x += addHtmlValue('Win32 Executable', 'MeshCentralRouter.exe'); + x += addHtmlValue('Win32 Executable', 'MeshCentralRouter.exe'); setDialogMode(2, "MeshCentral Router", 1, null, x, "fileDownload"); } diff --git a/webserver.js b/webserver.js index 77e27fc0..dfc2112b 100644 --- a/webserver.js +++ b/webserver.js @@ -2153,6 +2153,83 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { }); } + // Handle a Intel AMT activation request + function handleAmtActivateWebSocket(ws, req) { + const domain = checkUserIpAddress(ws, req); + if (domain == null) { ws.send(JSON.stringify({ errorText: 'Invalid domain' })); ws.close(); return; } + if (req.query.id == null) { ws.send(JSON.stringify({ errorText: 'Missing group identifier' })); ws.close(); return; } + + // Fetch the mesh object + ws.meshid = 'mesh/' + domain.id + '/' + req.query.id; + const mesh = obj.meshes[ws.meshid]; + if (mesh == null) { delete ws.meshid; ws.send(JSON.stringify({ errorText: 'Invalid device group' })); ws.close(); return; } + if (mesh.mtype != 1) { ws.send(JSON.stringify({ errorText: 'Invalid device group type' })); ws.close(); return; } + + // Fetch the remote IP:Port for logging + const remoteaddr = (req.ip.startsWith('::ffff:')) ? (req.ip.substring(7)) : req.ip; + ws.remoteaddrport = remoteaddr + ':' + ws._socket.remotePort; + + // When data is received from the web socket, echo it back + ws.on('message', function (data) { + // Parse the incoming command + var cmd = null; + try { cmd = JSON.parse(data); } catch (ex) { }; + if (cmd == null) return; + + // Process the command + switch (cmd.action) { + case 'acmactivate': { + // Check the command + if (cmd.version != 1) { ws.send(JSON.stringify({ errorText: 'Unsupported version' })); ws.close(); return; } + if (typeof cmd.hashes != 'object') { ws.send(JSON.stringify({ errorText: 'Invalid hashes' })); ws.close(); return; } + if (typeof cmd.fqdn != 'string') { ws.send(JSON.stringify({ errorText: 'Invalid FQDN' })); ws.close(); return; } + + // Get the current Intel AMT policy + var mesh = obj.meshes[ws.meshid]; + if ((mesh == null) || (mesh.amt == null) || (mesh.amt.type != 3) || (domain.amtacmactivation == null) || (domain.amtacmactivation.acmmatch == null) || (mesh.amt.password == null)) { ws.send(JSON.stringify({ errorText: 'Unable to activate' })); ws.close(); return; } + + // Check if we have a FQDN/Hash match + var matchingHash = null, matchingCN = null; + for (var i in domain.amtacmactivation.acmmatch) { + // Check for a matching FQDN + if ((domain.amtacmactivation.acmmatch[i].cn == '*') || (domain.amtacmactivation.acmmatch[i].cn.toLowerCase() == cmd.fqdn)) { + // Check for a matching certificate + if (cmd.hashes.indexOf(domain.amtacmactivation.acmmatch[i].sha256) >= 0) { + matchingCN = domain.amtacmactivation.acmmatch[i].cn; + matchingHash = domain.amtacmactivation.acmmatch[i].sha256; + continue; + } else if (cmd.hashes.indexOf(domain.amtacmactivation.acmmatch[i].sha1) >= 0) { + matchingCN = domain.amtacmactivation.acmmatch[i].cn; + matchingHash = domain.amtacmactivation.acmmatch[i].sha1; + continue; + } + } + } + if (matchingHash == null) { ws.send(JSON.stringify({ errorText: 'No matching activation certificates' })); ws.close(); return; } + if (matchingCN == '*') { ws.send(JSON.stringify({ errorText: 'Wildcard certificate activation not yet supported' })); ws.close(); return; } + cmd.hash = matchingHash; + + // Get the Intel AMT admin password, randomize if needed. + var amtpassword = ((mesh.amt.password == '') ? getRandomAmtPassword() : mesh.amt.password); + if (checkAmtPassword(amtpassword) == false) { ws.send(JSON.stringify({ errorText: 'Invalid Intel AMT password' })); ws.close(); return; } // Invalid Intel AMT password, this should never happen. + + // Agent is asking the server to sign an Intel AMT ACM activation request + var signResponse = parent.certificateOperations.signAcmRequest(domain, cmd, 'admin', amtpassword, ws.remoteaddrport, null, ws.meshid, null, null); + ws.send(JSON.stringify(signResponse)); + break; + } + default: { + // This is not a known command + ws.send(JSON.stringify({ errorText: 'Invalid command' })); ws.close(); return; + } + } + }); + + // If close or error, do nothing. + ws.on('error', function (err) { }); + ws.on('close', function (req) { }); + } + // Handle the web socket echo request, just echo back the data sent function handleEchoWebSocket(ws, req) { const domain = checkUserIpAddress(ws, req); @@ -2790,6 +2867,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { }); } + // Intel AMT ACM activation + if ((parent.config.domains[i].amtacmactivation != null) && (parent.config.domains[i].amtacmactivation.acmmatch != null)) { + obj.app.ws(url + 'amtactivate', handleAmtActivateWebSocket); + } + // Creates a login token using the user/pass that is passed in as URL arguments. // For example: https://localhost/createLoginToken.ashx?user=admin&pass=admin&a=3 // It's not advised to use this to create login tokens since the URL is often logged and you got credentials in the URL. @@ -3165,5 +3247,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // Return the query string portion of the URL, the ? and anything after. function getQueryPortion(req) { var s = req.url.indexOf('?'); if (s == -1) { if (req.body && req.body.urlargs) { return req.body.urlargs; } return ''; } return req.url.substring(s); } + // Generate a random Intel AMT password + function checkAmtPassword(p) { return (p.length > 7) && (/\d/.test(p)) && (/[a-z]/.test(p)) && (/[A-Z]/.test(p)) && (/\W/.test(p)); } + function getRandomAmtPassword() { var p; do { p = Buffer.from(obj.crypto.randomBytes(9), 'binary').toString('base64').split('/').join('@'); } while (checkAmtPassword(p) == false); return p; } + return obj; }; \ No newline at end of file