1
0
mirror of https://github.com/Ylianst/MeshCommander synced 2025-12-06 06:03:20 +00:00

Fixed Kerberos, added redirection error messages.

This commit is contained in:
Ylian Saint-Hilaire
2020-06-29 14:47:09 -07:00
parent 921f46f32b
commit c982c10e30
5 changed files with 223 additions and 54 deletions

View File

@@ -114,6 +114,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (accview.getUint32(0) != 0) { return obj.Stop(); } if (accview.getUint32(0) != 0) { return obj.Stop(); }
obj.send(String.fromCharCode(1)); // Send share desktop flag obj.send(String.fromCharCode(1)); // Send share desktop flag
obj.state = 3; obj.state = 3;
if (obj.parent) { obj.parent.disconnectCode = 50000; } // If Intel AMT disconnects at exactly this moment, indicates we need RLE8 or unsupported GPU.
} }
else if ((obj.state == 3) && (obj.acc.byteLength >= 24)) { else if ((obj.state == 3) && (obj.acc.byteLength >= 24)) {
// Getting server init // Getting server init
@@ -171,7 +172,7 @@ var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
if (obj.bpp == 1) obj.send(String.fromCharCode(0, 0, 0, 0, 8, 8, 0, 1) + ShortToStr(7) + ShortToStr(7) + ShortToStr(3) + String.fromCharCode(5, 2, 0, 0, 0, 0)); // Setup 8 bit color RGB332 if (obj.bpp == 1) obj.send(String.fromCharCode(0, 0, 0, 0, 8, 8, 0, 1) + ShortToStr(7) + ShortToStr(7) + ShortToStr(3) + String.fromCharCode(5, 2, 0, 0, 0, 0)); // Setup 8 bit color RGB332
obj.state = 4; obj.state = 4;
if (obj.parent) { obj.parent.xxStateChange(3); } if (obj.parent) { obj.parent.disconnectCode = 0; obj.parent.xxStateChange(3); }
_SendRefresh(); _SendRefresh();
//obj.timer = setInterval(obj.xxOnTimer, 50); //obj.timer = setInterval(obj.xxOnTimer, 50);

View File

@@ -28,6 +28,7 @@ var CreateAmtRedirect = function (module) {
obj.authuri = '/RedirectionService'; obj.authuri = '/RedirectionService';
obj.digestRealmMatch = null; obj.digestRealmMatch = null;
obj.onStateChanged = null; obj.onStateChanged = null;
obj.disconnectCode = 0;
function ToIntStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF), ((v >> 16) & 0xFF), ((v >> 24) & 0xFF)); } function ToIntStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF), ((v >> 16) & 0xFF), ((v >> 24) & 0xFF)); }
function ToShortStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF)); } function ToShortStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF)); }
@@ -95,6 +96,13 @@ var CreateAmtRedirect = function (module) {
obj.xxOnSocketData = function (data) { obj.xxOnSocketData = function (data) {
if (!data || obj.connectstate == -1) return; if (!data || obj.connectstate == -1) return;
// Redirection tracing
if (urlvars && urlvars['redirtrace']) {
var datastr = arrToStr(new Uint8Array(data));
console.log('REDIR-RECV(' + datastr.length + '): ' + rstr2hex(datastr));
}
//obj.inDataCount++; //obj.inDataCount++;
data = new Uint8Array(data).buffer; data = new Uint8Array(data).buffer;
@@ -129,6 +137,7 @@ var CreateAmtRedirect = function (module) {
cmdsize = (13 + oemlen); cmdsize = (13 + oemlen);
break; break;
default: default:
obj.disconnectCode = statuscode; // 2 = BUSY, 3 = UNSUPPORTED, 0xFF = ERROR.
obj.Stop(1); obj.Stop(1);
break; break;
} }
@@ -142,20 +151,49 @@ var CreateAmtRedirect = function (module) {
var authDataBuf = new Uint8Array(obj.acc.slice(9, 9 + authDataLen)); var authDataBuf = new Uint8Array(obj.acc.slice(9, 9 + authDataLen));
cmdsize = 9 + authDataLen; cmdsize = 9 + authDataLen;
if (authType == 0) { if (authType == 0) {
// Query // ###BEGIN###{Mode-NodeWebkit}
if (authData.indexOf(4) >= 0) { if (obj.user == '*') {
// Good Digest Auth (With cnonce and all) if (authData.indexOf(2) >= 0) {
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x04) + IntToStrX(obj.user.length + obj.authuri.length + 8) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00, 0x00)); // Kerberos Auth
var ticket;
if (kerberos && kerberos != null) {
var ticketReturn = kerberos.getTicket('HTTP' + ((obj.tls == 1)?'S':'') + '/' + ((obj.pass == '') ? (obj.host + ':' + obj.port) : obj.pass));
if (ticketReturn.returnCode == 0 || ticketReturn.returnCode == 0x90312) {
ticket = ticketReturn.ticket;
if (process.platform.indexOf('win') >= 0) {
// Clear kerberos tickets on both 32 and 64bit Windows platforms
try { require('child_process').exec('%windir%\\system32\\klist purge', function (error, stdout, stderr) { if (error) { require('child_process').exec('%windir%\\sysnative\\klist purge', function (error, stdout, stderr) { if (error) { console.error('Unable to purge kerberos tickets'); } }); } }); } catch (e) { console.log(e); }
}
} else {
console.error('Unexpected Kerberos error code: ' + ticketReturn.returnCode);
}
}
if (ticket) {
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x02) + IntToStrX(ticket.length) + ticket);
} else {
obj.Stop(2);
}
}
else obj.Stop(2);
} else {
// ###END###{Mode-NodeWebkit}
// Query
if (authData.indexOf(4) >= 0) {
// Good Digest Auth (With cnonce and all)
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x04) + IntToStrX(obj.user.length + obj.authuri.length + 8) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00, 0x00));
}
else if (authData.indexOf(3) >= 0) {
// Bad Digest Auth (Not sure why this is supported, cnonce is not used!)
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x03) + IntToStrX(obj.user.length + obj.authuri.length + 7) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00));
}
else if (authData.indexOf(1) >= 0) {
// Basic Auth (Probably a good idea to not support this unless this is an old version of Intel AMT)
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x01) + IntToStrX(obj.user.length + obj.pass.length + 2) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(obj.pass.length) + obj.pass);
}
else obj.Stop(2);
// ###BEGIN###{Mode-NodeWebkit}
} }
else if (authData.indexOf(3) >= 0) { // ###END###{Mode-NodeWebkit}
// Bad Digest Auth (Not sure why this is supported, cnonce is not used!)
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x03) + IntToStrX(obj.user.length + obj.authuri.length + 7) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(0x00, 0x00) + String.fromCharCode(obj.authuri.length) + obj.authuri + String.fromCharCode(0x00, 0x00, 0x00));
}
else if (authData.indexOf(1) >= 0) {
// Basic Auth (Probably a good idea to not support this unless this is an old version of Intel AMT)
obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x01) + IntToStrX(obj.user.length + obj.pass.length + 2) + String.fromCharCode(obj.user.length) + obj.user + String.fromCharCode(obj.pass.length) + obj.pass);
}
else obj.Stop(2);
} else if (((authType == 3) || (authType == 4)) && (status == 1)) { } else if (((authType == 3) || (authType == 4)) && (status == 1)) {
var curptr = 0; var curptr = 0;
@@ -261,7 +299,15 @@ var CreateAmtRedirect = function (module) {
} }
} }
obj.directSend = function (arr) { try { obj.socket.write(new Buffer(arr)); } catch (ex) { console.log(ex); } } obj.directSend = function (arr) {
// Redirection tracing
if (urlvars && urlvars['redirtrace']) {
var datastr = arrToStr(new Uint8Array(arr));
console.log('REDIR-DSEND(' + datastr.length + '): ' + rstr2hex(datastr));
}
try { obj.socket.write(new Buffer(arr)); } catch (ex) { console.log(ex); }
}
obj.xxSend = function (x) { obj.xxSend = function (x) {
if (urlvars && urlvars['redirtrace']) { console.log('REDIR-SEND(' + x.length + '): ' + rstr2hex(x)); } if (urlvars && urlvars['redirtrace']) { console.log('REDIR-SEND(' + x.length + '): ' + rstr2hex(x)); }

View File

@@ -206,12 +206,13 @@ var CreateWsmanComm = function (host, port, user, pass, tls, tlsoptions) {
} }
// Get the certificate of Intel AMT // Get the certificate of Intel AMT
obj.getPeerCertificate = function () { if (obj.xtls == 1) { return obj.socket.getPeerCertificate(); } return null; } obj.getPeerCertificate = function () { if (obj.xtls == 1) { return obj.xtlsCertificate; } return null; }
obj.getPeerCertificateFingerprint = function () { if (obj.xtls == 1) { return obj.socket.getPeerCertificate().fingerprint.split(':').join('').toLowerCase(); } return null; } obj.getPeerCertificateFingerprint = function () { if (obj.xtls == 1) { return obj.xtlsCertificate.fingerprint.split(':').join('').toLowerCase(); } return null; }
// NODE.js specific private method // NODE.js specific private method
obj.xxOnSocketConnected = function () { obj.xxOnSocketConnected = function () {
if (obj.socket == null) return; if (obj.socket == null) return;
obj.localAddress = obj.socket.localAddress; // Store the local address of this socket, useful for UEFI HTTPS boot
if (obj.xtls == 1) { if (obj.xtls == 1) {
obj.xtlsCertificate = obj.socket.getPeerCertificate(); obj.xtlsCertificate = obj.socket.getPeerCertificate();

View File

@@ -7779,6 +7779,11 @@
// ###BEGIN###{Mode-MeshCentral2} // ###BEGIN###{Mode-MeshCentral2}
QV('termRecordIcon', false); QV('termRecordIcon', false);
// ###END###{Mode-MeshCentral2} // ###END###{Mode-MeshCentral2}
if (terminal.disconnectCode == 2) { // BUSY
messagebox("Remote Terminal", "The remote device is busy, a session may already be open.");
} else if (terminal.disconnectCode == 3) { // UNSUPPORTED
messagebox("Remote Terminal", "The device indicated that this type of connection of not supported.");
}
break; break;
case 3: case 3:
// ###BEGIN###{Mode-MeshCentral2} // ###BEGIN###{Mode-MeshCentral2}
@@ -8180,6 +8185,13 @@
// ###BEGIN###{Mode-MeshCentral2} // ###BEGIN###{Mode-MeshCentral2}
QV('deskRecordIcon', false); QV('deskRecordIcon', false);
// ###END###{Mode-MeshCentral2} // ###END###{Mode-MeshCentral2}
if (desktop.disconnectCode == 2) { // BUSY
messagebox("Remote Desktop", "The remote device is busy, a session may already be open.");
} else if (desktop.disconnectCode == 3) { // UNSUPPORTED
messagebox("Remote Desktop", "The device indicated that this type of connection of not supported.");
} else if (desktop.disconnectCode == 50000) { // KVM-Disconnect
messagebox("Remote Desktop", "KVM disconnection, they may indicate that Intel AMT is unable to capture the display (Try RLE8 encoding), or unsupported GPU.");
}
break; break;
case 3: case 3:
// ###BEGIN###{DesktopInband} // ###BEGIN###{DesktopInband}
@@ -8402,11 +8414,21 @@
// Toggle desktop session recording // Toggle desktop session recording
function deskClipboard() { function deskClipboard() {
if (xxdialogMode || (desktop == null) || (desktop.State != 3)) return; if (xxdialogMode || (desktop == null) || (desktop.State != 3)) return;
setDialogMode(11, "Clipboard", 3, deskClipboardEx, "Enter text to send to Intel&reg; AMT clipboard." + '<br><textarea id=kvmClipText style=width:100%;height:120px;resize:none;margin-top:8px />'); var x = '';
x += "Enter text to send to Intel&reg; AMT clipboard." + '<br />';
x += '<select id=kvmClipEncoding style=width:100%;margin-top:8px><option value=0>' + "Text Encoding" + '<option value=1>' + "Hex Encoding" + '</select>';
x += '<textarea id=kvmClipText style=width:100%;height:120px;resize:none;margin-top:8px />';
setDialogMode(11, "Clipboard", 3, deskClipboardEx, x);
focusTextBox('kvmClipText'); focusTextBox('kvmClipText');
} }
function deskClipboardEx() { desktop.m.sendClipboardData(Q('kvmClipText').value.split('\\0').join('\0')); } function deskClipboardEx() {
if (Q('kvmClipEncoding').value == 0) {
desktop.m.sendClipboardData(Q('kvmClipText').value.split('\\0').join('\0')); // Text encoded input
} else {
desktop.m.sendClipboardData(hex2rstr(Q('kvmClipText').value)); // Hex encoded input
}
}
// ###END###{DesktopClipboard} // ###END###{DesktopClipboard}
// ###BEGIN###{FileSaver} // ###BEGIN###{FileSaver}
@@ -9878,7 +9900,7 @@
addOption('d5actionSelect', "Power on to PXE", 401); addOption('d5actionSelect', "Power on to PXE", 401);
// ###BEGIN###{PowerControl-Advanced} // ###BEGIN###{PowerControl-Advanced}
// ###BEGIN###{PowerControl-OneClick} // ###BEGIN###{PowerControl-OneClick}
if (amtPowerBootCapabilities['ForceUEFIHTTPSBoot'] == true) { if (amtPowerBootCapabilities['ForceUEFIHTTPSBoot'] === true) {
addOption('d5actionSelect', "Reset to HTTPS Boot", 600); addOption('d5actionSelect', "Reset to HTTPS Boot", 600);
addOption('d5actionSelect', "Power on to HTTPS Boot", 601); addOption('d5actionSelect', "Power on to HTTPS Boot", 601);
} }
@@ -9908,7 +9930,7 @@
setDialogMode(11, "HTTPS Boot", 3, function () { setDialogMode(11, "HTTPS Boot", 3, function () {
var files = Q('ocrfile').files; var files = Q('ocrfile').files;
if (files.length != 1) return; if (files.length != 1) return;
webserver.setupBootImage(files[0].path, wsstack.comm.socket.localAddress); webserver.setupBootImage(files[0].path, wsstack.comm.localAddress);
powerActionDlg(); powerActionDlg();
}, x); }, x);
QE('idx_dlgOkButton', false); QE('idx_dlgOkButton', false);
@@ -10257,6 +10279,7 @@
if (action == 300 || action == 301) { bootSource = 'Force Diagnostic Boot'; } if (action == 300 || action == 301) { bootSource = 'Force Diagnostic Boot'; }
if (action == 400 || action == 401) { bootSource = 'Force PXE Boot'; } if (action == 400 || action == 401) { bootSource = 'Force PXE Boot'; }
// ###BEGIN###{PowerControl-Advanced} // ###BEGIN###{PowerControl-Advanced}
if (action == 600 || action == 601) { bootSource = 'Force OCR UEFI HTTPS Boot'; }
} }
// Resetting Force boot data in case it was changed so that it won't be used on the next power action // Resetting Force boot data in case it was changed so that it won't be used on the next power action

View File

@@ -12,16 +12,18 @@ var CreateWebServer = function () {
const path = require("path"); const path = require("path");
var obj = {}; var obj = {};
var server = null; var server = null;
obj.port = random(1, 65535); // Port used to listen for incoming requests. obj.port = random(33000, 65500); // Port used to listen for incoming requests.
obj.state = 0; // State of the web server, 0 = Disabled, 2 = Listening. obj.state = 0; // State of the web server, 0 = Disabled, 2 = Listening.
obj.cert = null; // TLS certificate in PEM format. obj.rootCert = null; // Root certificate in PEM format.
obj.key = null; // TLS certificate private key in PEM format. obj.rootKey = null; // Root certificate private key in PEM format.
obj.certHashRaw = null; // SHA384 hash of TLS certificate. obj.cert = null; // TLS certificate in PEM format.
obj.certHashHex = null; // SHA384 hash of TLS certificate in HEX. obj.key = null; // TLS certificate private key in PEM format.
obj.responses = {}; // Table responses to different url paths. obj.certHashRaw = null; // SHA384 hash of TLS certificate.
obj.transfers = []; // List of currently active file transfers. obj.certHashHex = null; // SHA384 hash of TLS certificate in HEX.
obj.transfersTimer = null; // When file transfers are active, this is a half second timer. obj.responses = {}; // Table responses to different url paths.
obj.onTransfers = null; // Callback for transfers status. obj.transfers = []; // List of currently active file transfers.
obj.transfersTimer = null; // When file transfers are active, this is a half second timer.
obj.onTransfers = null; // Callback for transfers status.
obj.lastBootImageArgs = null; obj.lastBootImageArgs = null;
// Return a random number between min and max // Return a random number between min and max
@@ -32,7 +34,7 @@ var CreateWebServer = function () {
if (server != null) return; if (server != null) return;
obj.state = 1; obj.state = 1;
if ((obj.cert != null) && (obj.key != null)) { server = tls.createServer({ cert: obj.cert, key: obj.key, minVersion: 'TLSv1' }, onConnection); } else { server = net.createServer(onConnection); } if ((obj.cert != null) && (obj.key != null)) { server = tls.createServer({ cert: obj.cert, key: obj.key, minVersion: 'TLSv1' }, onConnection); } else { server = net.createServer(onConnection); }
server.on('error', function (err) { if (err.code == 'EADDRINUSE') { obj.port = random(1, 65535); server = null; obj.start(func); } else { console.log('WebServer Listen Error', err.code); } }); server.on('error', function (err) { if (err.code == 'EADDRINUSE') { obj.port = random(33000, 65500); server = null; obj.start(func); } else { console.log('WebServer Listen Error', err.code); } });
server.listen({ port: obj.port }, function (x) { obj.state = 2; console.log('WebServer listening on ' + obj.port); if (func != null) { func(); } }); server.listen({ port: obj.port }, function (x) { obj.state = 2; console.log('WebServer listening on ' + obj.port); if (func != null) { func(); } });
} }
@@ -100,30 +102,99 @@ var CreateWebServer = function () {
obj.stop = function () { if (server == null) return; server.close(); server = null; } obj.stop = function () { if (server == null) return; server.close(); server = null; }
// Generate a TLS certificate (this is really a root cert) // Generate a TLS certificate (this is really a root cert)
obj.generateCertificate = function() { obj.generateCertificate = function () {
// Generate a keypair and create an X.509v3 certificate var attrs1 = [{ name: 'commonName', value: 'MeshCommanderRoot' }, { name: 'countryName', value: 'Unknown' }, { shortName: 'ST', value: 'Unknown' }, { name: 'organizationName', value: 'Unknown' }];
var keys = forge.pki.rsa.generateKeyPair(1024); var attrs2 = [{ name: 'commonName', value: 'MeshCommander.com' }, { name: 'countryName', value: 'Unknown' }, { shortName: 'ST', value: 'Unknown' }, { name: 'organizationName', value: 'Unknown' }];
var cert = forge.pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.serialNumber = '' + Math.floor((Math.random() * 100000) + 1);
cert.validity.notBefore = new Date(2018, 0, 1);
cert.validity.notAfter = new Date(2049, 11, 31);
var attrs = [ { name: 'commonName', value: 'MeshCommander' }, { name: 'countryName', value: 'Unknown' }, { shortName: 'ST', value: 'Unknown' }, { name: 'organizationName', value: 'Unknown' } ];
cert.setSubject(attrs);
cert.setIssuer(attrs);
cert.setExtensions([{ name: 'basicConstraints', cA: true }, { name: 'nsCertType', sslCA: true, emailCA: true, objCA: true }, { name: 'subjectKeyIdentifier' }]); // Root extensions
cert.sign(keys.privateKey, forge.md.sha256.create());
obj.cert = forge.pki.certificateToPem(cert);
obj.key = forge.pki.privateKeyToPem(keys.privateKey);
// Compute the SHA384 hash of the certificate if (fs.existsSync('webroot.pem') && fs.existsSync('webroot.key')) {
var md = forge.md.sha384.create(); console.log('Read root from file');
obj.rootCert = fs.readFileSync('webroot.pem').toString();
obj.rootKey = fs.readFileSync('webroot.key').toString();
var rootcert = forge.pki.certificateFromPem(obj.rootCert);
var rootkeys = { privateKey: forge.pki.privateKeyFromPem(obj.rootKey) };
} else {
console.log('Generate root');
// Generate a root keypair and create an X.509v3 root certificate
var rootkeys = forge.pki.rsa.generateKeyPair(1024);
var rootcert = forge.pki.createCertificate();
rootcert.publicKey = rootkeys.publicKey;
rootcert.serialNumber = '' + Math.floor((Math.random() * 100000) + 1);
rootcert.validity.notBefore = new Date(2018, 0, 1);
rootcert.validity.notAfter = new Date(2049, 11, 31);
rootcert.setSubject(attrs1);
rootcert.setIssuer(attrs1);
rootcert.setExtensions([{ name: 'basicConstraints', cA: true }, { name: 'nsCertType', sslCA: true, emailCA: true, objCA: true }, { name: 'subjectKeyIdentifier' }]); // Root extensions
rootcert.sign(rootkeys.privateKey, forge.md.sha256.create());
obj.rootCert = forge.pki.certificateToPem(rootcert);
obj.rootKey = forge.pki.privateKeyToPem(rootkeys.privateKey);
fs.writeFileSync('webroot.pem', obj.rootCert);
fs.writeFileSync('webroot.key', obj.rootKey);
}
if (fs.existsSync('webleaf.pem') && fs.existsSync('webleaf.key')) {
console.log('Read leaf from file');
obj.cert = fs.readFileSync('webleaf.pem').toString();
obj.key = fs.readFileSync('webleaf.key').toString();
var cert = forge.pki.certificateFromPem(obj.cert);
var keys = { privateKey: forge.pki.privateKeyFromPem(obj.key) };
} else {
console.log('Generate leaf');
// Generate a keypair and create an X.509v3 certificate
var keys = forge.pki.rsa.generateKeyPair(1024);
var cert = forge.pki.createCertificate();
cert.publicKey = keys.publicKey;
cert.serialNumber = '' + Math.floor((Math.random() * 100000) + 1);
cert.validity.notBefore = new Date(2018, 0, 1);
cert.validity.notAfter = new Date(2049, 11, 31);
cert.setSubject(attrs2);
cert.setIssuer(attrs1);
// Figure out the extended key usages
var extKeyUsage = { name: 'extKeyUsage', serverAuth: true }
// Create a leaf certificate
cert.setExtensions([{ name: 'basicConstraints' }, { name: 'keyUsage', keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true }, extKeyUsage, { name: 'nsCertType', server: true }, { name: 'subjectKeyIdentifier' }]);
// Self-sign certificate
cert.sign(rootkeys.privateKey, forge.md.sha256.create());
obj.cert = forge.pki.certificateToPem(cert);
obj.key = forge.pki.privateKeyToPem(keys.privateKey);
fs.writeFileSync('webleaf.pem', obj.cert);
fs.writeFileSync('webleaf.key', obj.key);
}
// Compute the SHA256 hash of the certificate
var md = forge.md.sha256.create();
md.start(); md.update(forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes()); md.start(); md.update(forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes());
var digest = md.digest(); var digest = md.digest();
obj.certHashRaw = digest.data; obj.certHashRaw = digest.data;
obj.certHashHex = digest.toHex(); obj.certHashHex = digest.toHex();
console.log('SHA256', md.digest().toHex());
// Compute the SHA384 hash of the certificate
md = forge.md.sha384.create();
md.start(); md.update(forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes());
console.log('SHA384', md.digest().toHex());
// Compute the SHA512 hash of the certificate
md = forge.md.sha512.create();
md.start(); md.update(forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes());
console.log('SHA512', md.digest().toHex());
} }
// MC 0.8.6
// 8680 0100 2c000000 68747470733a2f2f31302e3135312e3133372e3139383a343133352f34343131313435323237343935353831 // https://10.151.137.198:4135/4411145227495581
// 8680 1400 01000000 00 // OCR_HTTPS_CERT_SYNC_ROOT_CA
// 8680 1700 20000000 ac8adfe3809dc66990040fdaac53765e369c0242f2a789327b57c072d5dd2677
// 8680 1e00 02000000 3c00 // OCR_HTTPS_REQUEST_TIMEOUT (60)
// MC 0.8.3-alpha
// 8680 0100 2c000000 68747470733a2f2f31302e3135312e3133372e3139383a343133352f34343131313435323237343935353831 // https://10.151.137.198:4135/4411145227495581
// 8680 0300 02000000 2c00 // OCR_EFI_FILE_DEVICE_PATH (44)
// 8680 1700 20000000 ac8adfe3809dc66990040fdaac53765e369c0242f2a789327b57c072d5dd2677
// 8680 1400 01000000 00 // OCR_HTTPS_CERT_SYNC_ROOT_CA
// 8680 1e00 02000000 0000 // OCR_HTTPS_REQUEST_TIMEOUT
// Returns a UEFI boot parameter in binary // Returns a UEFI boot parameter in binary
function makeUefiBootParam(type, data, len) { function makeUefiBootParam(type, data, len) {
if (typeof data == 'number') { if (len == 1) { data = String.fromCharCode(data & 0xFF); } if (len == 2) { data = ShortToStrX(data); } if (len == 4) { data = IntToStrX(data); } } if (typeof data == 'number') { if (len == 1) { data = String.fromCharCode(data & 0xFF); } if (len == 2) { data = ShortToStrX(data); } if (len == 4) { data = IntToStrX(data); } }
@@ -135,15 +206,42 @@ var CreateWebServer = function () {
if (fs.existsSync(filePath) == false) return null; if (fs.existsSync(filePath) == false) return null;
var name = ('' + Math.random()).substring(2); var name = ('' + Math.random()).substring(2);
obj.responses['/' + name] = { type: 'application/octet-stream', file: filePath }; obj.responses['/' + name] = { type: 'application/octet-stream', file: filePath };
console.log('https://' + ip + ':' + obj.port + '/' + name); var url = 'http' + ((obj.cert != null) ? 's' : '') + '://' + ip + ':' + obj.port + '/' + name;
console.log(url);
/*
obj.lastBootImageArgs = { obj.lastBootImageArgs = {
args: btoa( args: btoa(
makeUefiBootParam(1, 'http' + ((obj.cert != null)?'s':'') + '://' + ip + ':' + obj.port + '/' + name) + // OCR_EFI_NETWORK_DEVICE_PATH makeUefiBootParam(1, url) + // OCR_EFI_NETWORK_DEVICE_PATH (1)
makeUefiBootParam(20, 0, 1) + // OCR_HTTPS_CERT_SYNC_ROOT_CA makeUefiBootParam(3, url.length, 2) + // OCR_EFI_DEVICE_PATH_LEN (3)
makeUefiBootParam(23, obj.certHashRaw) + // OCR_HTTPS_SERVER_CERT_HASH_SHA384 makeUefiBootParam(20, 0, 1) + // OCR_HTTPS_CERT_SYNC_ROOT_CA (20) (0 = false)
makeUefiBootParam(30, 60, 2)), // OCR_HTTPS_REQUEST_TIMEOUT (60 seconds) makeUefiBootParam(21, "MeshCommander.com") + // OCR_HTTPS_CERT_SERVER_NAME (21)
makeUefiBootParam(22, 1, 2) + // OCR_HTTPS_SERVER_NAME_VERIFY_METHOD (22) (1 = FullName)
makeUefiBootParam(23, obj.certHashRaw) + // OCR_HTTPS_SERVER_CERT_HASH_SHA256 (23)
makeUefiBootParam(30, 0, 2)), // OCR_HTTPS_REQUEST_TIMEOUT (30) (0 seconds = default)
argscount: 7
};
obj.lastBootImageArgs = {
args: btoa(
makeUefiBootParam(1, url) + // OCR_EFI_NETWORK_DEVICE_PATH (1)
makeUefiBootParam(20, 0, 1) + // OCR_HTTPS_CERT_SYNC_ROOT_CA (20) (0 = false)
makeUefiBootParam(21, "MeshCommander.com") + // OCR_HTTPS_CERT_SERVER_NAME (21)
makeUefiBootParam(22, 1, 2) + // OCR_HTTPS_SERVER_NAME_VERIFY_METHOD (22) (1 = FullName)
makeUefiBootParam(23, obj.certHashRaw)), // OCR_HTTPS_SERVER_CERT_HASH_SHA256 (23)
argscount: 5
};
*/
obj.lastBootImageArgs = {
args: btoa(
makeUefiBootParam(1, url) + // OCR_EFI_NETWORK_DEVICE_PATH (1)
makeUefiBootParam(20, 1, 1) + // OCR_HTTPS_CERT_SYNC_ROOT_CA (20) (0 = false)
makeUefiBootParam(21, "MeshCommander.com") + // OCR_HTTPS_CERT_SERVER_NAME (21)
makeUefiBootParam(22, 1, 2)), // OCR_HTTPS_SERVER_NAME_VERIFY_METHOD (22) (1 = FullName)
argscount: 4 argscount: 4
}; };
return obj.lastBootImageArgs; return obj.lastBootImageArgs;
} }