More work on Intel AMT One Click Recovery.

Ylian Saint-Hilaire committed Mar 23, 2021 at 11:23 UTC a8d1f32cfbb12aab992c82d30966f066d40bf5fe
2 files changed +48 -32
amtmanager.js
+2 -6
@@ -866,14 +866,10 @@ module.exports.CreateAmtManager = function (parent) {
866 if (status != 200) { dev.consoleMsg("Failed to get boot settings data (" + status + ")."); delete dev.ocrfile; return; }
867
868 // Generate the one-time URL.
869 - //var cookie = obj.parent.encodeCookie({ a: 'ocr', f: dev.ocrfile }, obj.parent.loginCookieEncryptionKey)
870 - //var url = 'https://' + parent.webserver.certificates.AmtMpsName + ':' + ((parent.args.mpsaliasport != null) ? parent.args.mpsaliasport : parent.args.mpsport) + '/ocr/' + cookie + '.iso';
869 + var cookie = obj.parent.encodeCookie({ a: 'f', f: dev.ocrfile }, obj.parent.loginCookieEncryptionKey)
870 + var url = 'https://' + parent.webserver.certificates.AmtMpsName + ':' + ((parent.args.mpsaliasport != null) ? parent.args.mpsaliasport : parent.args.mpsport) + '/c/' + cookie + '.iso';
871 delete dev.ocrfile;
872
873 - // DEBUG
874 - var url = 'https://' + parent.webserver.certificates.AmtMpsName + ':' + ((parent.args.mpsaliasport != null) ? parent.args.mpsaliasport : parent.args.mpsport) + '/ocr/abc.iso';
875 - console.log('OCR: ' + url);
876 -
873 // Generate the boot data for OCR with URL
874 var r = response.Body;
875 r['UefiBootParametersArray'] = Buffer.from(makeUefiBootParam(1, url) + makeUefiBootParam(20, 1, 1) + makeUefiBootParam(30, 0, 2), 'binary').toString('base64');
mpsserver.js
+46 -26
@@ -1185,36 +1185,56 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
1185 if ((directives.length != 3) || ((directives[0] != 'GET') && (directives[0] != 'HEAD'))) { this.end(); return; }
1186 //console.log('WebServer, request', directives[0], directives[1]);
1187 var responseCode = 404, responseType = 'application/octet-stream', responseData = '', r = null;
1188 - if (obj.httpResponses != null) { r = obj.httpResponses[directives[1]]; }
1189 - if ((r != null) && (r.maxtime != null) && (r.maxtime < Date.now())) { r = null; delete obj.httpResponses[directives[1]]; } // Check if this entry is expired.
1190 - if (r != null) {
1191 - if (typeof r == 'string') {
1192 - responseCode = 200; responseType = 'text/html'; responseData = r;
1193 - } else if (typeof r == 'object') {
1194 - responseCode = 200;
1195 - if (r.type) { responseType = r.type; }
1196 - if (r.data) { responseData = r.data; }
1197 - if (r.shortfile) { try { responseData = obj.fs.readFileSync(r.shortfile); } catch (ex) { responseCode = 404; responseType = 'text/html'; responseData = 'File not found'; } }
1198 - if (r.file) {
1199 - // Send the file header and pipe the rest of the file
1200 - var filestats = null;
1201 - try { filestats = obj.fs.statSync(r.file); } catch (ex) { }
1202 - if ((filestats == null) || (typeof filestats.size != 'number') || (filestats.size <= 0)) {
1203 - responseCode = 404; responseType = 'text/html'; responseData = 'File not found';
1204 - } else {
1205 - this.write('HTTP/1.1 200 OK\r\n' + hostHeader + 'Content-Type: ' + responseType + '\r\nConnection: keep-alive\r\nContent-Length: ' + filestats.size + '\r\n\r\n');
1206 - if (directives[0] == 'GET') {
1207 - obj.fs.createReadStream(r.file, { flags: 'r' }).pipe(this);
1208 - if (typeof r.maxserve == 'number') { r.maxserve--; if (r.maxserve == 0) { delete obj.httpResponses[directives[1]]; } } // Check if this entry was server the maximum amount of times.
1188 +
1189 + // Check if this is a cookie request
1190 + if (directives[1].startsWith('/c/')) {
1191 + var cookie = obj.parent.decodeCookie(directives[1].substring(3).split('.')[0], obj.parent.loginCookieEncryptionKey, 30); // 30 minute timeout
1192 + if ((cookie != null) && (cookie.a == 'f') && (typeof cookie.f == 'string')) {
1193 + // Send the file header and pipe the rest of the file
1194 + var filestats = null;
1195 + try { filestats = obj.fs.statSync(cookie.f); } catch (ex) { }
1196 + if ((filestats == null) || (typeof filestats.size != 'number') || (filestats.size <= 0)) {
1197 + responseCode = 404; responseType = 'text/html'; responseData = 'File not found';
1198 + } else {
1199 + this.write('HTTP/1.1 200 OK\r\n' + hostHeader + 'Content-Type: ' + responseType + '\r\nConnection: keep-alive\r\nContent-Length: ' + filestats.size + '\r\n\r\n');
1200 + if (directives[0] == 'GET') { obj.fs.createReadStream(cookie.f, { flags: 'r' }).pipe(this); }
1201 + delete this.xdata;
1202 + return;
1203 + }
1204 + }
1205 + } else {
1206 + // Check if we have a preset response
1207 + if (obj.httpResponses != null) { r = obj.httpResponses[directives[1]]; }
1208 + if ((r != null) && (r.maxtime != null) && (r.maxtime < Date.now())) { r = null; delete obj.httpResponses[directives[1]]; } // Check if this entry is expired.
1209 + if (r != null) {
1210 + if (typeof r == 'string') {
1211 + responseCode = 200; responseType = 'text/html'; responseData = r;
1212 + } else if (typeof r == 'object') {
1213 + responseCode = 200;
1214 + if (r.type) { responseType = r.type; }
1215 + if (r.data) { responseData = r.data; }
1216 + if (r.shortfile) { try { responseData = obj.fs.readFileSync(r.shortfile); } catch (ex) { responseCode = 404; responseType = 'text/html'; responseData = 'File not found'; } }
1217 + if (r.file) {
1218 + // Send the file header and pipe the rest of the file
1219 + var filestats = null;
1220 + try { filestats = obj.fs.statSync(r.file); } catch (ex) { }
1221 + if ((filestats == null) || (typeof filestats.size != 'number') || (filestats.size <= 0)) {
1222 + responseCode = 404; responseType = 'text/html'; responseData = 'File not found';
1223 + } else {
1224 + this.write('HTTP/1.1 200 OK\r\n' + hostHeader + 'Content-Type: ' + responseType + '\r\nConnection: keep-alive\r\nContent-Length: ' + filestats.size + '\r\n\r\n');
1225 + if (directives[0] == 'GET') {
1226 + obj.fs.createReadStream(r.file, { flags: 'r' }).pipe(this);
1227 + if (typeof r.maxserve == 'number') { r.maxserve--; if (r.maxserve == 0) { delete obj.httpResponses[directives[1]]; } } // Check if this entry was server the maximum amount of times.
1228 + }
1229 + delete this.xdata;
1230 + return;
1231 }
1210 - delete this.xdata;
1211 - return;
1232 }
1233 }
1234 + } else {
1235 + responseType = 'text/html';
1236 + responseData = 'Invalid request';
1237 }
1215 - } else {
1216 - responseType = 'text/html';
1217 - responseData = 'Invalid request';
1238 }
1239 this.write('HTTP/1.1 ' + responseCode + ' OK\r\n' + hostHeader + 'Connection: keep-alive\r\nContent-Type: ' + responseType + '\r\nContent-Length: ' + responseData.length + '\r\n\r\n');
1240 this.write(responseData);