Added IDER to MeshCMD, fixed MeshAgent connection exception.
Ylian Saint-Hilaire committed
Jun 6, 2019 at 09:59 UTC
59ae4933ba8408367d5ed974fcc4644b6b04b189
10 files changed
+1045
-6
agents/MeshCmd-signed.exe
Binary files a/agents/MeshCmd-signed.exe and b/agents/MeshCmd-signed.exe differ
agents/MeshCmd64-signed.exe
Binary files a/agents/MeshCmd64-signed.exe and b/agents/MeshCmd64-signed.exe differ
agents/meshcmd.js
+65
-1
@@ -45,7 +45,7 @@ var wsstack = null, amtstack = null;
45
var oswsstack = null, osamtstack = null;
46
var amtMeiTmpState = null;
47
var SMBiosTables = null;
48
-var globalDebugFlags = 0;
48
+var globalDebugFlags = 0; // 1 = IDER Debug
49
const RCSMessageProtocolVersion = 1; // RCS Message Protocol Version. Needs to be less than or equal to RCS server Message Protocol Version
50
51
// MeshCommander for Firmware (GZIP'ed, Base64) v0.7.5
@@ -128,6 +128,10 @@ function run(argv) {
128
if ((typeof args.script) == 'string') { settings.script = args.script; }
129
if ((typeof args.agent) == 'string') { settings.agent = args.agent; }
130
if ((typeof args.proxy) == 'string') { settings.proxy = args.proxy; }
131
+ if ((typeof args.floppy) == 'string') { settings.floppy = args.floppy; }
132
+ if ((typeof args.cdrom) == 'string') { settings.cdrom = args.cdrom; }
133
+ if ((typeof args.timeout) == 'string') { settings.timeout = parseInt(args.timeout); }
134
+ if (args.debug === true) { settings.debuglevel = 1; }
135
if (args.debug) { try { waitForDebugger(); } catch (e) { } }
136
if (args.noconsole) { settings.noconsole = true; }
137
if (args.nocommander) { settings.noconsole = true; }
@@ -163,6 +167,7 @@ function run(argv) {
167
console.log(' AmtSaveState - Save all Intel AMT WSMAN object to file.');
168
console.log(' AmtPresence - Heartbeat a local Intel AMT watchdog agent.');
169
console.log(' AmtScript - Run .mescript on Intel AMT.');
170
+ console.log(' AmtIDER - Mount local disk image to remote computer.');
171
console.log('\r\nHelp on a specific action using:\r\n');
172
console.log(' meshcmd help [action]');
173
exit(1); return;
@@ -274,6 +279,16 @@ function run(argv) {
279
console.log(' --user [username] The Intel AMT login username, admin is default.');
280
console.log(' --pass [password] The Intel AMT login password.');
281
console.log(' --tls Specifies that TLS must be used.');
282
+ } else if (action == 'amtider') {
283
+ console.log('AmtIDER will mount a local disk images to a remote Intel AMT computer. Example usage:\r\n\r\n meshcmd amtider --host 1.2.3.4 --user admin --pass mypassword --tls --floppy disk.img --cdrom disk.iso');
284
+ console.log('\r\nPossible arguments:\r\n');
285
+ console.log(' --host [hostname] The IP address or DNS name of Intel AMT.');
286
+ console.log(' --user [username] The Intel AMT login username, admin is default.');
287
+ console.log(' --pass [password] The Intel AMT login password.');
288
+ console.log(' --tls Specifies that TLS must be used.');
289
+ console.log(' --floppy [file] Specifies .img file to be mounted as a flppy disk.');
290
+ console.log(' --cdrom [file] Specifies .img file to be mounted as a CDROM disk.');
291
+ console.log(' --timeout [seconds] Optional, disconnect after number of seconds without disk read.');
292
} else {
293
actions.shift();
294
console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
@@ -492,6 +507,14 @@ function run(argv) {
507
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
508
} else { settings.hostname = '127.0.0.1'; }
509
readAmtAuditLog();
510
+ } else if (settings.action == 'amtider') { // Remote mount IDER image
511
+ if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { console.log('No or invalid \"hostname\" specified, use --hostname [password].'); exit(1); return; }
512
+ if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
513
+ if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
514
+ if ((settings.floppy == null) || (typeof settings.floppy != 'string') || (settings.floppy == '')) { settings.floppy = null; }
515
+ if ((settings.cdrom == null) || (typeof settings.cdrom != 'string') || (settings.cdrom == '')) { settings.cdrom = null; }
516
+ if ((settings.floppy == null) && (settings.cdrom == null)) { console.log('No or invalid \"floppy\" or \"cdrom\" specified, use --floppy [file] or --cdrom [file].'); exit(1); return; }
517
+ performIder();
518
} else {
519
console.log('Invalid \"action\" specified.'); exit(1); return;
520
}
@@ -1818,6 +1841,47 @@ function deleteStorage(name, func, noretry) {
1841
req.end();
1842
}
1843
1844
+
1845
+//
1846
+// IDER
1847
+//
1848
+
1849
+ider = null;
1850
+iderIdleTimer = null;
1851
+
1852
+// Perform IDER
1853
+function performIder() {
1854
+ if ((settings.floppy != null) && fs.existsSync(settings.floppy) == false) { console.log("Unable to floppy image file: " + settings.floppy); process.exit(); return; }
1855
+ if ((settings.cdrom != null) && fs.existsSync(settings.cdrom) == false) { console.log("Unable to CDROM image file: " + settings.cdrom); process.exit(); return; }
1856
+ try {
1857
+ var sfloppy = null, scdrom = null;
1858
+ if (settings.floppy) { try { if (sfloppy = fs.statSync(settings.floppy)) { sfloppy.file = fs.openSync(settings.floppy, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } }
1859
+ if (settings.cdrom) { try { scdrom = fs.statSync(settings.cdrom); if (scdrom) { scdrom.file = fs.openSync(settings.cdrom, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } }
1860
+
1861
+ ider = require('amt-redir-duk')(require('amt-ider')());
1862
+ ider.onStateChanged = onIderStateChange;
1863
+ ider.m.floppy = sfloppy;
1864
+ ider.m.cdrom = scdrom;
1865
+ ider.m.iderStart = 1; // OnReboot = 0, Graceful = 1, Now = 2
1866
+ ider.m.debug = (settings.debuglevel > 0);
1867
+ if (settings.timeout > 0) { ider.m.sectorStats = iderSectorStats; }
1868
+ //ider.digestRealmMatch = wsstack.comm.digestRealm;
1869
+ //ider.tlsv1only = amtstack.wsman.comm.tlsv1only;
1870
+ ider.Start(settings.hostname, (settings.tls == true)?16995:16994, settings.username ? 'admin' : settings.username, settings.password, settings.tls);
1871
+ } catch (ex) { console.log(ex); }
1872
+}
1873
+
1874
+function onIderStateChange(stack, state) { console.log(['Disconnected', 'Connecting...', 'Connected...', 'Started IDER...'][state]);}
1875
+
1876
+function iderSectorStats(mode, dev, mediaBlocks, lba, len) {
1877
+ if (iderIdleTimer != null) { clearTimeout(iderIdleTimer); }
1878
+ iderIdleTimer = setTimeout(function () { console.log('Idle timeout'); process.exit(1); }, 1000 * settings.timeout);
1879
+}
1880
+
1881
+//
1882
+// Startup
1883
+//
1884
+
1885
// Parse URL arguments
1886
function parseUrlArguments(url) {
1887
var r = {}, x = url.split('?');
agents/meshcmd.min.js
+65
-1
@@ -45,7 +45,7 @@ var wsstack = null, amtstack = null;
45
var oswsstack = null, osamtstack = null;
46
var amtMeiTmpState = null;
47
var SMBiosTables = null;
48
-var globalDebugFlags = 0;
48
+var globalDebugFlags = 0; // 1 = IDER Debug
49
const RCSMessageProtocolVersion = 1; // RCS Message Protocol Version. Needs to be less than or equal to RCS server Message Protocol Version
50
51
// MeshCommander for Firmware (GZIP'ed, Base64) v0.7.5
@@ -128,6 +128,10 @@ function run(argv) {
128
if ((typeof args.script) == 'string') { settings.script = args.script; }
129
if ((typeof args.agent) == 'string') { settings.agent = args.agent; }
130
if ((typeof args.proxy) == 'string') { settings.proxy = args.proxy; }
131
+ if ((typeof args.floppy) == 'string') { settings.floppy = args.floppy; }
132
+ if ((typeof args.cdrom) == 'string') { settings.cdrom = args.cdrom; }
133
+ if ((typeof args.timeout) == 'string') { settings.timeout = parseInt(args.timeout); }
134
+ if (args.debug === true) { settings.debuglevel = 1; }
135
if (args.debug) { try { waitForDebugger(); } catch (e) { } }
136
if (args.noconsole) { settings.noconsole = true; }
137
if (args.nocommander) { settings.noconsole = true; }
@@ -163,6 +167,7 @@ function run(argv) {
167
console.log(' AmtSaveState - Save all Intel AMT WSMAN object to file.');
168
console.log(' AmtPresence - Heartbeat a local Intel AMT watchdog agent.');
169
console.log(' AmtScript - Run .mescript on Intel AMT.');
170
+ console.log(' AmtIDER - Mount local disk image to remote computer.');
171
console.log('\r\nHelp on a specific action using:\r\n');
172
console.log(' meshcmd help [action]');
173
exit(1); return;
@@ -274,6 +279,16 @@ function run(argv) {
279
console.log(' --user [username] The Intel AMT login username, admin is default.');
280
console.log(' --pass [password] The Intel AMT login password.');
281
console.log(' --tls Specifies that TLS must be used.');
282
+ } else if (action == 'amtider') {
283
+ console.log('AmtIDER will mount a local disk images to a remote Intel AMT computer. Example usage:\r\n\r\n meshcmd amtider --host 1.2.3.4 --user admin --pass mypassword --tls --floppy disk.img --cdrom disk.iso');
284
+ console.log('\r\nPossible arguments:\r\n');
285
+ console.log(' --host [hostname] The IP address or DNS name of Intel AMT.');
286
+ console.log(' --user [username] The Intel AMT login username, admin is default.');
287
+ console.log(' --pass [password] The Intel AMT login password.');
288
+ console.log(' --tls Specifies that TLS must be used.');
289
+ console.log(' --floppy [file] Specifies .img file to be mounted as a flppy disk.');
290
+ console.log(' --cdrom [file] Specifies .img file to be mounted as a CDROM disk.');
291
+ console.log(' --timeout [seconds] Optional, disconnect after number of seconds without disk read.');
292
} else {
293
actions.shift();
294
console.log('Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: ' + actions.join(', ') + '.');
@@ -492,6 +507,14 @@ function run(argv) {
507
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
508
} else { settings.hostname = '127.0.0.1'; }
509
readAmtAuditLog();
510
+ } else if (settings.action == 'amtider') { // Remote mount IDER image
511
+ if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { console.log('No or invalid \"hostname\" specified, use --hostname [password].'); exit(1); return; }
512
+ if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
513
+ if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
514
+ if ((settings.floppy == null) || (typeof settings.floppy != 'string') || (settings.floppy == '')) { settings.floppy = null; }
515
+ if ((settings.cdrom == null) || (typeof settings.cdrom != 'string') || (settings.cdrom == '')) { settings.cdrom = null; }
516
+ if ((settings.floppy == null) && (settings.cdrom == null)) { console.log('No or invalid \"floppy\" or \"cdrom\" specified, use --floppy [file] or --cdrom [file].'); exit(1); return; }
517
+ performIder();
518
} else {
519
console.log('Invalid \"action\" specified.'); exit(1); return;
520
}
@@ -1818,6 +1841,47 @@ function deleteStorage(name, func, noretry) {
1841
req.end();
1842
}
1843
1844
+
1845
+//
1846
+// IDER
1847
+//
1848
+
1849
+ider = null;
1850
+iderIdleTimer = null;
1851
+
1852
+// Perform IDER
1853
+function performIder() {
1854
+ if ((settings.floppy != null) && fs.existsSync(settings.floppy) == false) { console.log("Unable to floppy image file: " + settings.floppy); process.exit(); return; }
1855
+ if ((settings.cdrom != null) && fs.existsSync(settings.cdrom) == false) { console.log("Unable to CDROM image file: " + settings.cdrom); process.exit(); return; }
1856
+ try {
1857
+ var sfloppy = null, scdrom = null;
1858
+ if (settings.floppy) { try { if (sfloppy = fs.statSync(settings.floppy)) { sfloppy.file = fs.openSync(settings.floppy, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } }
1859
+ if (settings.cdrom) { try { scdrom = fs.statSync(settings.cdrom); if (scdrom) { scdrom.file = fs.openSync(settings.cdrom, 'rbN'); } } catch (ex) { console.log(ex); process.exit(1); return; } }
1860
+
1861
+ ider = require('amt-redir-duk')(require('amt-ider')());
1862
+ ider.onStateChanged = onIderStateChange;
1863
+ ider.m.floppy = sfloppy;
1864
+ ider.m.cdrom = scdrom;
1865
+ ider.m.iderStart = 1; // OnReboot = 0, Graceful = 1, Now = 2
1866
+ ider.m.debug = (settings.debuglevel > 0);
1867
+ if (settings.timeout > 0) { ider.m.sectorStats = iderSectorStats; }
1868
+ //ider.digestRealmMatch = wsstack.comm.digestRealm;
1869
+ //ider.tlsv1only = amtstack.wsman.comm.tlsv1only;
1870
+ ider.Start(settings.hostname, (settings.tls == true)?16995:16994, settings.username ? 'admin' : settings.username, settings.password, settings.tls);
1871
+ } catch (ex) { console.log(ex); }
1872
+}
1873
+
1874
+function onIderStateChange(stack, state) { console.log(['Disconnected', 'Connecting...', 'Connected...', 'Started IDER...'][state]);}
1875
+
1876
+function iderSectorStats(mode, dev, mediaBlocks, lba, len) {
1877
+ if (iderIdleTimer != null) { clearTimeout(iderIdleTimer); }
1878
+ iderIdleTimer = setTimeout(function () { console.log('Idle timeout'); process.exit(1); }, 1000 * settings.timeout);
1879
+}
1880
+
1881
+//
1882
+// Startup
1883
+//
1884
+
1885
// Parse URL arguments
1886
function parseUrlArguments(url) {
1887
var r = {}, x = url.split('?');
agents/modules_meshcmd/amt-ider.js
new
+601
@@ -0,0 +1,601 @@
1
+/**
2
+* @description IDER Handling Module
3
+* @author Ylian Saint-Hilaire
4
+*/
5
+
6
+// meshservice meshcmd.js amtider --host 192.168.2.186 --pass P@ssw0rd --floppy msdos.img
7
+
8
+// Construct a Intel AMT IDER object
9
+module.exports = function CreateAmtRemoteIder() {
10
+ var obj = {};
11
+ obj.protocol = 3; // IDER
12
+ obj.bytesToAmt = 0;
13
+ obj.bytesFromAmt = 0;
14
+ obj.rx_timeout = 30000; // Default 30000
15
+ obj.tx_timeout = 0; // Default 0
16
+ obj.heartbeat = 20000; // Default 20000
17
+ obj.version = 1;
18
+ obj.acc = null;
19
+ obj.inSequence = 0;
20
+ obj.outSequence = 0;
21
+ obj.iderinfo = null;
22
+ obj.enabled = false;
23
+ obj.iderStart = 0; // OnReboot = 0, Graceful = 1, Now = 2
24
+ obj.floppy = null;
25
+ obj.cdrom = null;
26
+ obj.floppyReady = false;
27
+ obj.cdromReady = false;
28
+ //obj.pingTimer = null;
29
+ obj.sectorStats = null;
30
+ obj.debug = false;
31
+
32
+ // Mode Sense
33
+ var IDE_ModeSence_LS120Disk_Page_Array = new Buffer([0x00, 0x26, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x1E, 0x10, 0xA9, 0x08, 0x20, 0x02, 0x00, 0x03, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xD0, 0x00, 0x00]);
34
+ var IDE_ModeSence_3F_LS120_Array = new Buffer([0x00, 0x5c, 0x24, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x16, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x1E, 0x10, 0xA9, 0x08, 0x20, 0x02, 0x00, 0x03, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xD0, 0x00, 0x00, 0x08, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x11, 0x24, 0x31]);
35
+ var IDE_ModeSence_FloppyDisk_Page_Array = new Buffer([0x00, 0x26, 0x24, 0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x1E, 0x04, 0xB0, 0x02, 0x12, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xD0, 0x00, 0x00]);
36
+ var IDE_ModeSence_3F_Floppy_Array = new Buffer([0x00, 0x5c, 0x24, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x16, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x1e, 0x04, 0xb0, 0x02, 0x12, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xd0, 0x00, 0x00, 0x08, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x11, 0x24, 0x31]);
37
+ var IDE_ModeSence_CD_1A_Array = new Buffer([0x00, 0x12, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
38
+ //var IDE_ModeSence_CD_1B_Array = new Buffer([0x00, 0x12, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
39
+ var IDE_ModeSence_CD_1D_Array = new Buffer([0x00, 0x12, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
40
+ var IDE_ModeSence_CD_2A_Array = new Buffer([0x00, 0x20, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x18, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
41
+ //var IDE_ModeSence_CD_01_Array = new Buffer([0x00, 0x0E, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00]);
42
+ var IDE_ModeSence_3F_CD_Array = new Buffer([0x00, 0x28, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x18, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
43
+
44
+ // 0x46 constant data
45
+ var IDE_CD_ConfigArrayHeader = new Buffer([0x00, 0x00,0x00, 0x28, 0x00, 0x00, 0x00, 0x08]);
46
+ var IDE_CD_ConfigArrayProfileList = new Buffer([0x00, 0x00, 0x03, 0x04, 0x00, 0x08, 0x01, 0x00]);
47
+ var IDE_CD_ConfigArrayCore = new Buffer([0x00, 0x01, 0x03, 0x04, 0x00, 0x00, 0x00, 0x02]);
48
+ var IDE_CD_Morphing = new Buffer([0x00, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00]);
49
+ var IDE_CD_ConfigArrayRemovable = new Buffer([0x00, 0x03, 0x03, 0x04, 0x29, 0x00, 0x00, 0x02]);
50
+ var IDE_CD_ConfigArrayRandom = new Buffer([0x00, 0x10, 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00]);
51
+ var IDE_CD_Read = new Buffer([0x00, 0x1E, 0x03, 0x00]);
52
+ var IDE_CD_PowerManagement = new Buffer([0x01, 0x00, 0x03, 0x00]);
53
+ var IDE_CD_Timeout = new Buffer([0x01, 0x05, 0x03, 0x00]);
54
+
55
+ // 0x01 constant data
56
+ var IDE_ModeSence_FloppyError_Recovery_Array = new Buffer([0x00, 0x12, 0x24, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00]);
57
+ var IDE_ModeSence_Ls120Error_Recovery_Array = new Buffer([0x00, 0x12, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0A, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00]);
58
+ var IDE_ModeSence_CDError_Recovery_Array = new Buffer([0x00, 0x0E, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00]);
59
+
60
+
61
+ // Private method, called by parent when it change state
62
+ obj.xxStateChange = function (newstate) {
63
+ if (obj.debug) console.log("IDER-StateChange", newstate);
64
+ if (newstate == 0) { obj.Stop(); }
65
+ if (newstate == 3) { obj.Start(); }
66
+ }
67
+
68
+ obj.Start = function () {
69
+ if (obj.debug) { console.log("IDER-Start"); console.log(obj.floppy, obj.cdrom); }
70
+ obj.bytesToAmt = 0;
71
+ obj.bytesFromAmt = 0;
72
+ obj.inSequence = 0;
73
+ obj.outSequence = 0;
74
+ g_readQueue = [];
75
+
76
+ // Send first command, OPEN_SESSION
77
+ obj.SendCommand(0x40, Buffer.concat([ ShortToStrX(obj.rx_timeout), ShortToStrX(obj.tx_timeout), ShortToStrX(obj.heartbeat), IntToStrX(obj.version) ]));
78
+
79
+ // Send sector stats
80
+ if (obj.sectorStats) {
81
+ obj.sectorStats(0, 0, obj.floppy ? (obj.floppy.size >> 9) : 0);
82
+ obj.sectorStats(0, 1, obj.cdrom ? (obj.cdrom.size >> 11) : 0);
83
+ }
84
+
85
+ // Setup the ping timer
86
+ //obj.pingTimer = setInterval(function () { obj.SendCommand(0x44); }, 5000);
87
+ }
88
+
89
+ obj.Stop = function () {
90
+ if (obj.debug) console.log("IDER-Stop");
91
+ //if (obj.pingTimer) { clearInterval(obj.pingTimer); obj.pingTimer = null; }
92
+ obj.parent.Stop();
93
+ }
94
+
95
+ // Private method
96
+ obj.ProcessData = function (data) {
97
+ obj.bytesFromAmt += data.length;
98
+ if (obj.acc == null) { obj.acc = data; } else { obj.acc = Buffer.concat(obj.acc, data); }
99
+ if (obj.debug) console.log('IDER-ProcessData', obj.acc.length, obj.acc.toString('hex'));
100
+
101
+ // Process as many commands as possible
102
+ while (obj.acc != null) {
103
+ var len = obj.ProcessDataEx();
104
+ if (len == 0) return;
105
+ if (obj.inSequence != ReadIntX(obj.acc, 4)) {
106
+ if (obj.debug) console.log('ERROR: Out of sequence', obj.inSequence, ReadIntX(obj.acc, 4));
107
+ obj.Stop();
108
+ return;
109
+ }
110
+ obj.inSequence++;
111
+ if (len == obj.acc.length) { obj.acc = null; } else { obj.acc = obj.acc.slice(len); }
112
+ }
113
+ }
114
+
115
+ // Private method
116
+ obj.SendCommand = function (cmdid, data, completed, dma) {
117
+ if (data == null) { data = new Buffer(0); }
118
+ var attributes = ((cmdid > 50) && (completed == true)) ? 2 : 0;
119
+ if (dma) { attributes += 1; }
120
+ var x = Buffer.concat([Buffer([cmdid, 0, 0, attributes]), IntToStrX(obj.outSequence++), data]);
121
+ obj.parent.xxSend(x);
122
+ obj.bytesToAmt += x.length;
123
+ //if (cmdid != 0x4B) { console.log('IDER-SendData', x.length, x.toString('hex')); }
124
+ }
125
+
126
+ // CommandEndResponse (SCSI_SENSE)
127
+ obj.SendCommandEndResponse = function (error, sense, device, asc, asq) {
128
+ if (error) { obj.SendCommand(0x51, new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xc5, 0, 3, 0, 0, 0, device, 0x50, 0, 0, 0]), true); }
129
+ else { obj.SendCommand(0x51, new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x87, (sense << 4), 3, 0, 0, 0, device, 0x51, sense, asc, asq]), true); }
130
+ }
131
+
132
+ // DataToHost (SCSI_READ)
133
+ obj.SendDataToHost = function (device, completed, data, dma) {
134
+ var dmalen = (dma) ? 0 : data.length;
135
+ if (completed == true) {
136
+ obj.SendCommand(0x54, Buffer.concat([new Buffer([0, (data.length & 0xff), (data.length >> 8), 0, dma ? 0xb4 : 0xb5, 0, 2, 0, (dmalen & 0xff), (dmalen >> 8), device, 0x58, 0x85, 0, 3, 0, 0, 0, device, 0x50, 0, 0, 0, 0, 0, 0]), data ]), completed, dma);
137
+ } else {
138
+ obj.SendCommand(0x54, Buffer.concat([new Buffer([0, (data.length & 0xff), (data.length >> 8), 0, dma ? 0xb4 : 0xb5, 0, 2, 0, (dmalen & 0xff), (dmalen >> 8), device, 0x58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), data]), completed, dma);
139
+ }
140
+ }
141
+
142
+ // GetDataFromHost (SCSI_CHUNK)
143
+ obj.SendGetDataFromHost = function (device, chunksize) {
144
+ obj.SendCommand(0x52, new Buffer([0, (chunksize & 0xff), (chunksize >> 8), 0, 0xb5, 0, 0, 0, (chunksize & 0xff), (chunksize >> 8), device, 0x58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), false);
145
+ }
146
+
147
+ // DisableEnableFeatures (STATUS_DATA)
148
+ // If type is REGS_TOGGLE (3), 4 bytes of data must be provided.
149
+ obj.SendDisableEnableFeatures = function (type, data) { if (data == null) { data = ''; } obj.SendCommand(0x48, Buffer.concat([new Buffer([type]), data])); }
150
+
151
+ // Private method
152
+ obj.ProcessDataEx = function () {
153
+ if (obj.acc.length < 8) return 0;
154
+
155
+ // First 8 bytes are the header
156
+ // CommandID + 0x000000 + Sequence Number
157
+ //console.log('ProcessDataEx', obj.acc[0]);
158
+
159
+ switch(obj.acc[0]) {
160
+ case 0x41: // OPEN_SESSION
161
+ if (obj.acc.length < 30) return 0;
162
+ var len = obj.acc[29];
163
+ if (obj.acc.length < (30 + len)) return 0;
164
+ obj.iderinfo = {};
165
+ obj.iderinfo.major = obj.acc[8];
166
+ obj.iderinfo.minor = obj.acc[9];
167
+ obj.iderinfo.fwmajor = obj.acc[10];
168
+ obj.iderinfo.fwminor = obj.acc[11];
169
+ obj.iderinfo.readbfr = ReadShortX(obj.acc, 16);
170
+ obj.iderinfo.writebfr = ReadShortX(obj.acc, 18);
171
+ obj.iderinfo.proto = obj.acc[21];
172
+ obj.iderinfo.iana = ReadIntX(obj.acc, 25);
173
+ if (obj.debug) console.log(obj.iderinfo);
174
+
175
+ if (obj.iderinfo.proto != 0) {
176
+ if (obj.debug) console.log("Unknown proto", obj.iderinfo.proto);
177
+ obj.Stop();
178
+ }
179
+ if (obj.iderinfo.readbfr > 8192) {
180
+ if (obj.debug) console.log("Illegal read buffer size", obj.iderinfo.readbfr);
181
+ obj.Stop();
182
+ }
183
+ if (obj.iderinfo.writebfr > 8192) {
184
+ if (obj.debug) console.log("Illegal write buffer size", obj.iderinfo.writebfr);
185
+ obj.Stop();
186
+ }
187
+
188
+ if (obj.iderStart == 0) { obj.SendDisableEnableFeatures(3, IntToStrX(0x01 + 0x08)); } // OnReboot
189
+ else if (obj.iderStart == 1) { obj.SendDisableEnableFeatures(3, IntToStrX(0x01 + 0x10)); } // Graceful
190
+ else if (obj.iderStart == 2) { obj.SendDisableEnableFeatures(3, IntToStrX(0x01 + 0x18)); } // Now
191
+ //obj.SendDisableEnableFeatures(1); // GetSupportedFeatures
192
+ return 30 + len;
193
+ case 0x43: // CLOSE
194
+ if (obj.debug) console.log('CLOSE');
195
+ obj.Stop();
196
+ return 8;
197
+ case 0x44: // KEEPALIVEPING
198
+ obj.SendCommand(0x45); // Send PONG back
199
+ return 8;
200
+ case 0x45: // KEEPALIVEPONG
201
+ if (obj.debug) console.log('PONG');
202
+ return 8;
203
+ case 0x46: // RESETOCCURED
204
+ if (obj.acc.length < 9) return 0;
205
+ var resetMask = obj.acc[8];
206
+ if (g_media === null) {
207
+ // No operations are pending
208
+ obj.SendCommand(0x47); // Send ResetOccuredResponse
209
+ if (obj.debug) console.log('RESETOCCURED1', resetMask);
210
+ } else {
211
+ // Operations are being done, sent the reset once completed.
212
+ g_reset = true;
213
+ if (obj.debug) console.log('RESETOCCURED2', resetMask);
214
+ }
215
+ return 9;
216
+ case 0x49: // STATUS_DATA - DisableEnableFeaturesReply
217
+ if (obj.acc.length < 13) return 0;
218
+ var type = obj.acc[8];
219
+ var value = ReadIntX(obj.acc, 9);
220
+ if (obj.debug) console.log('STATUS_DATA', type, value);
221
+ switch (type)
222
+ {
223
+ case 1: // REGS_AVAIL
224
+ if (value & 1) {
225
+ if (obj.iderStart == 0) { obj.SendDisableEnableFeatures(3, IntToStrX(0x01 + 0x08)); } // OnReboot
226
+ else if (obj.iderStart == 1) { obj.SendDisableEnableFeatures(3, IntToStrX(0x01 + 0x10)); } // Graceful
227
+ else if (obj.iderStart == 2) { obj.SendDisableEnableFeatures(3, IntToStrX(0x01 + 0x18)); } // Now
228
+ }
229
+ break;
230
+ case 2: // REGS_STATUS
231
+ obj.enabled = (value & 2) ? true : false;
232
+ if (obj.debug) console.log("IDER Status: " + obj.enabled);
233
+ break;
234
+ case 3: // REGS_TOGGLE
235
+ if (value != 1) {
236
+ if (obj.debug) console.log("Register toggle failure");
237
+ } //else { obj.SendDisableEnableFeatures(2); }
238
+ break;
239
+ }
240
+ return 13;
241
+ case 0x4A: // ERROR OCCURED
242
+ if (obj.acc.length < 11) return 0;
243
+ if (obj.debug) console.log('IDER: ABORT', obj.acc[8]);
244
+ //obj.Stop();
245
+ return 11;
246
+ case 0x4B: // HEARTBEAT
247
+ //console.log('HEARTBEAT');
248
+ return 8;
249
+ case 0x50: // COMMAND WRITTEN
250
+ if (obj.acc.length < 28) return 0;
251
+ var device = (obj.acc[14] & 0x10) ? 0xB0 : 0xA0;
252
+ var deviceFlags = obj.acc[14];
253
+ var cdb = obj.acc.slice(16, 28);
254
+ var featureRegister = obj.acc[9];
255
+ if (obj.debug) console.log('SCSI_CMD', device, cdb.toString('hex'), featureRegister, deviceFlags);
256
+ handleSCSI(device, cdb, featureRegister, deviceFlags);
257
+ return 28;
258
+ case 0x53: // DATA FROM HOST
259
+ if (obj.acc.length < 14) return 0;
260
+ var len = ReadShortX(obj.acc, 9);
261
+ if (obj.acc.length < (14 + len)) return 0;
262
+ if (obj.debug) console.log('SCSI_WRITE, len = ' + (14 + len));
263
+ obj.SendCommand(0x51, new Buffer([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x70, 0x03, 0x00, 0x00, 0x00, 0xa0, 0x51, 0x07, 0x27, 0x00]), true);
264
+ return 14 + len;
265
+ default:
266
+ if (obj.debug) console.log('Unknown IDER command', obj.acc[0]);
267
+ obj.Stop();
268
+ break;
269
+ }
270
+ return 0;
271
+ }
272
+
273
+ function handleSCSI(dev, cdb, featureRegister, deviceFlags)
274
+ {
275
+ var lba;
276
+ var len;
277
+
278
+ switch(cdb[0])
279
+ {
280
+ case 0x00: // TEST_UNIT_READY:
281
+ if (obj.debug) console.log("SCSI: TEST_UNIT_READY", dev);
282
+ switch (dev) {
283
+ case 0xA0: // DEV_FLOPPY
284
+ if (obj.floppy == null) { obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); return -1; }
285
+ if (obj.floppyReady == false) { obj.floppyReady = true; obj.SendCommandEndResponse(1, 0x06, dev, 0x28, 0x00); return -1; } // Switch to ready
286
+ break;
287
+ case 0xB0: // DEV_CDDVD
288
+ if (obj.cdrom == null) { obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); return -1; }
289
+ if (obj.cdromReady == false) { obj.cdromReady = true; obj.SendCommandEndResponse(1, 0x06, dev, 0x28, 0x00); return -1; } // Switch to ready
290
+ break;
291
+ default:
292
+ if (obj.debug) console.log("SCSI Internal error 3", dev);
293
+ return -1;
294
+ }
295
+ obj.SendCommandEndResponse(1, 0x00, dev, 0x00, 0x00); // Indicate ready
296
+ break;
297
+ case 0x08: // READ_6
298
+ lba = ((cdb[1] & 0x1f) << 16) + (cdb[2] << 8) + cdb[3];
299
+ len = cdb[4];
300
+ if (len == 0) { len = 256; }
301
+ if (obj.debug) console.log("SCSI: READ_6", dev, lba, len);
302
+ sendDiskData(dev, lba, len, featureRegister);
303
+ break;
304
+ case 0x0a: // WRITE_6
305
+ lba = ((cdb[1] & 0x1f) << 16) + (cdb[2] << 8) + cdb[3];
306
+ len = cdb[4];
307
+ if (len == 0) { len = 256; }
308
+ if (obj.debug) console.log("SCSI: WRITE_6", dev, lba, len);
309
+ obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); // Write is not supported, remote no medium.
310
+ return -1;
311
+ /*
312
+ case 0x15: // MODE_SELECT_6:
313
+ console.log("SCSI ERROR: MODE_SELECT_6", dev);
314
+ obj.SendCommandEndResponse(1, 0x05, dev, 0x20, 0x00);
315
+ return -1;
316
+ */
317
+ case 0x1a: // MODE_SENSE_6
318
+ if (obj.debug) console.log("SCSI: MODE_SENSE_6", dev);
319
+ if ((cdb[2] == 0x3f) && (cdb[3] == 0x00)) {
320
+ var a = 0, b = 0;
321
+ switch (dev) {
322
+ case 0xA0: // DEV_FLOPPY
323
+ if (obj.floppy == null) { obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); return -1; }
324
+ a = 0x00;
325
+ b = 0x80; // Read only = 0x80, Read write = 0x00
326
+ break;
327
+ case 0xB0: // DEV_CDDVD
328
+ if (obj.cdrom == null) { obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); return -1; }
329
+ a = 0x05;
330
+ b = 0x80;
331
+ break;
332
+ default:
333
+ if (obj.debug) console.log("SCSI Internal error 6", dev);
334
+ return -1;
335
+ }
336
+ obj.SendDataToHost(dev, true, new Buffer([0, a, b, 0]), featureRegister & 1);
337
+ return;
338
+ }
339
+ obj.SendCommandEndResponse(1, 0x05, dev, 0x24, 0x00);
340
+ break;
341
+ case 0x1b: // START_STOP (Called when you eject the CDROM)
342
+ //var immediate = cdb[1] & 0x01;
343
+ //var loej = cdb[4] & 0x02;
344
+ //var start = cdb[4] & 0x01;
345
+ obj.SendCommandEndResponse(1, 0, dev);
346
+ break;
347
+ case 0x1e: // LOCK_UNLOCK - ALLOW_MEDIUM_REMOVAL
348
+ if (obj.debug) console.log("SCSI: ALLOW_MEDIUM_REMOVAL", dev);
349
+ if ((dev == 0xA0) && (obj.floppy == null)) { obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); return -1; }
350
+ if ((dev == 0xB0) && (obj.cdrom == null)) { obj.SendCommandEndResponse(1, 0x02, dev, 0x3a, 0x00); return -1; }
351
+ obj.SendCommandEndResponse(1, 0x00, dev, 0x00, 0x00);
352
+ break;
353
+ case 0x23: // READ_FORMAT_CAPACITIES (Floppy only)
354
+ if (obj.debug) console.log("SCSI: READ_FORMAT_CAPACITIES", dev);
355
+ var buflen = ReadShort(cdb, 7);
356
+ var mediaStatus = 0, sectors;
357
+ var mcSize = buflen / 8; // Capacity descriptor size is 8
358
+
359
+ switch (dev) {
360
+ case 0xA0: // DEV_FLOPPY
361
+ if ((obj.floppy == null) || (obj.floppy.size == 0)) { obj.SendCommandEndResponse(0, 0x05, dev, 0x24, 0x00); return -1; }
362
+ sectors = (obj.floppy.size >> 9) - 1;
363
+ break;
364
+ case 0xB0: // DEV_CDDVD
365
+ if ((obj.cdrom == null) || (obj.cdrom.size == 0)) { obj.SendCommandEndResponse(0, 0x05, dev, 0x24, 0x00); return -1; }
366
+ sectors = (obj.cdrom.size >> 11) - 1; // Number 2048 byte blocks
367
+ break;
368
+ default:
369
+ if (obj.debug) console.log("SCSI Internal error 4", dev);
370
+ return -1;
371
+ }
372
+
373
+ obj.SendDataToHost(dev, true, Buffer.concat([ IntToStr(8), new Buffer([0x00, 0x00, 0x0b, 0x40, 0x02, 0x00, 0x02, 0x00]) ]), featureRegister & 1);
374
+ break;
375
+ case 0x25: // READ_CAPACITY
376
+ if (obj.debug) console.log("SCSI: READ_CAPACITY", dev);
377
+ var len = 0;
378
+ switch(dev)
379
+ {
380
+ case 0xA0: // DEV_FLOPPY
381
+ if ((obj.floppy == null) || (obj.floppy.size == 0)) { obj.SendCommandEndResponse(0, 0x02, dev, 0x3a, 0x00); return -1; }
382
+ if (obj.floppy != null) { len = (obj.floppy.size >> 9) - 1; }
383
+ if (obj.debug) console.log('DEV_FLOPPY', len); // Number 512 byte blocks
384
+ break;
385
+ case 0xB0: // DEV_CDDVD
386
+ if ((obj.cdrom == null) || (obj.cdrom.size == 0)) { obj.SendCommandEndResponse(0, 0x02, dev, 0x3a, 0x00); return -1; }
387
+ if (obj.cdrom != null) { len = (obj.cdrom.size >> 11) - 1; } // Number 2048 byte blocks
388
+ if (obj.debug) console.log('DEV_CDDVD', len);
389
+ break;
390
+ default:
391
+ if (obj.debug) console.log("SCSI Internal error 4", dev);
392
+ return -1;
393
+ }
394
+ //if (dev == 0xA0) { dev = 0x00; } else { dev = 0x10; } // Weird but seems to work.
395
+ if (obj.debug) console.log("SCSI: READ_CAPACITY2", dev, deviceFlags);
396
+ obj.SendDataToHost(deviceFlags, true, Buffer.concat([IntToStr(len), new Buffer([0, 0, ((dev == 0xB0) ? 0x08 : 0x02), 0])]), featureRegister & 1);
397
+ break;
398
+ case 0x28: // READ_10
399
+ lba = ReadInt(cdb, 2);
400
+ len = ReadShort(cdb, 7);
401
+ if (obj.debug) console.log("SCSI: READ_10", dev, lba, len);
402
+ sendDiskData(dev, lba, len, featureRegister);
403
+ break;
404
+ case 0x2a: // WRITE_10 (Floppy only)
405
+ case 0x2e: // WRITE_AND_VERIFY (Floppy only)
406
+ lba = ReadInt(cdb, 2);
407
+ len = ReadShort(cdb, 7);
408
+ if (obj.debug) console.log("SCSI: WRITE_10", dev, lba, len);
409
+ obj.SendGetDataFromHost(dev, 512 * len); // Floppy writes only, accept sectors of 512 bytes
410
+ break;
411
+ case 0x43: // READ_TOC (CD Audio only)
412
+ var buflen = ReadShort(cdb, 7);
413
+ var msf = cdb[1] & 0x02;
414
+ var format = cdb[2] & 0x07;
415
+ if (format == 0) { format = cdb[9] >> 6; }
416
+ if (obj.debug) console.log("SCSI: READ_TOC, dev=" + dev + ", buflen=" + buflen + ", msf=" + msf + ", format=" + format);
417
+
418
+ switch (dev) {
419
+ case 0xA0: // DEV_FLOPPY
420
+ obj.SendCommandEndResponse(1, 0x05, dev, 0x20, 0x00); // Not implemented
421
+ return -1;
422
+ case 0xB0: // DEV_CDDVD
423
+ // NOP
424
+ break;
425
+ default:
426
+ if (obj.debug) console.log("SCSI Internal error 9", dev);
427
+ return -1;
428
+ }
429
+
430
+ if (format == 1) { obj.SendDataToHost(dev, true, new Buffer([0x00, 0x0a, 0x01, 0x01, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00]), featureRegister & 1); }
431
+ else if (format == 0) {
432
+ if (msf) {
433
+ obj.SendDataToHost(dev, true, new Buffer([0x00, 0x12, 0x01, 0x01, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x14, 0xaa, 0x00, 0x00, 0x00, 0x34, 0x13]), featureRegister & 1);
434
+ } else {
435
+ obj.SendDataToHost(dev, true, new Buffer([0x00, 0x12, 0x01, 0x01, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00]), featureRegister & 1);
436
+ }
437
+ }
438
+ break;
439
+ case 0x46: // GET_CONFIGURATION
440
+ var sendall = (cdb[1] != 2);
441
+ var firstcode = ReadShort(cdb, 2);
442
+ var buflen = ReadShort(cdb, 7);
443
+
444
+ if (obj.debug) console.log("SCSI: GET_CONFIGURATION", dev, sendall, firstcode, buflen);
445
+ if (buflen == 0) { obj.SendDataToHost(dev, true, Buffer.concat([IntToStr(0x003c), IntToStr(0x0008)]), featureRegister & 1); return -1; } // TODO: Fixed this return, it's not correct.
446
+
447
+ // Set the header
448
+ var r = null;
449
+
450
+ // Add the data
451
+ if (firstcode == 0) { r = IDE_CD_ConfigArrayProfileList; }
452
+ if ((firstcode == 0x1) || (sendall && (firstcode < 0x1))) { r = IDE_CD_ConfigArrayCore; }
453
+ if ((firstcode == 0x2) || (sendall && (firstcode < 0x2))) { r = IDE_CD_Morphing; }
454
+ if ((firstcode == 0x3) || (sendall && (firstcode < 0x3))) { r = IDE_CD_ConfigArrayRemovable; }
455
+ if ((firstcode == 0x10) || (sendall && (firstcode < 0x10))) { r = IDE_CD_ConfigArrayRandom; }
456
+ if ((firstcode == 0x1E) || (sendall && (firstcode < 0x1E))) { r = IDE_CD_Read; }
457
+ if ((firstcode == 0x100) || (sendall && (firstcode < 0x100))) { r = IDE_CD_PowerManagement; }
458
+ if ((firstcode == 0x105) || (sendall && (firstcode < 0x105))) { r = IDE_CD_Timeout; }
459
+
460
+ if (r == null) {
461
+ //console.log('NOT RIGHT', sendall, firstcode, cdb[2], cdb[3]);
462
+ //process.exit(0);
463
+ r = Buffer.concat([IntToStr(0x0008), IntToStr(4)]);
464
+ } else {
465
+ r = Buffer.concat([IntToStr(0x0008), IntToStr(r.length + 4), r]);
466
+ }
467
+
468
+ // Cut the length to buflen if needed
469
+ if (r.length > buflen) { r = r.slice(0, buflen); }
470
+
471
+ obj.SendDataToHost(dev, true, r, featureRegister & 1);
472
+ return -1;
473
+ case 0x4a: // GET_EV_STATUS - GET_EVENT_STATUS_NOTIFICATION
474
+ //var buflen = (cdb[7] << 8) + cdb[8];
475
+ //if (buflen == 0) { obj.SendDataToHost(dev, true, Buffer.concat([IntToStr(0x003c), IntToStr(0x0008)]), featureRegister & 1); return -1; } // TODO: Fixed this return, it's not correct.
476
+ if (obj.debug) console.log("SCSI: GET_EVENT_STATUS_NOTIFICATION", dev, cdb[1], cdb[4], cdb[9]);
477
+ if ((cdb[1] != 0x01) && (cdb[4] != 0x10)) {
478
+ if (obj.debug) console.log('SCSI ERROR');
479
+ obj.SendCommandEndResponse(1, 0x05, dev, 0x26, 0x01);
480
+ break;
481
+ }
482
+ var present = 0x00;
483
+ if ((dev == 0xA0) && (obj.floppy != null)) { present = 0x02; }
484
+ else if ((dev == 0xB0) && (obj.cdrom != null)) { present = 0x02; }
485
+ obj.SendDataToHost(dev, true, new Buffer([0x00, present, 0x80, 0x00]), featureRegister & 1); // This is the original version, 4 bytes long
486
+ break;
487
+ case 0x4c:
488
+ obj.SendCommand(0x51, Buffer.concat([ IntToStrX(0), IntToStrX(0), IntToStrX(0), new Buffer([0x87, 0x50, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x51, 0x05, 0x20, 0x00]) ]), true);
489
+ break;
490
+ case 0x51: // READ_DISC_INFO
491
+ if (obj.debug) console.log("SCSI READ_DISC_INFO", dev);
492
+ obj.SendCommandEndResponse(0, 0x05, dev, 0x20, 0x00); // Correct
493
+ return -1;
494
+ case 0x55: // MODE_SELECT_10:
495
+ if (obj.debug) console.log("SCSI ERROR: MODE_SELECT_10", dev);
496
+ obj.SendCommandEndResponse(1, 0x05, dev, 0x20, 0x00);
497
+ return -1;
498
+ case 0x5a: // MODE_SENSE_10
499
+ if (obj.debug) console.log("SCSI: MODE_SENSE_10", dev, cdb[2] & 0x3f);
500
+ var buflen = ReadShort(cdb, 7);
501
+ //var pc = cdb[2] & 0xc0;
502
+ var r = null;
503
+
504
+ if (buflen == 0) { obj.SendDataToHost(dev, true, Buffer.concat([IntToStr(0x003c), IntToStr(0x0008)]), featureRegister & 1); return -1; } // TODO: Fixed this return, it's not correct.
505
+
506
+ // 1.44 mb floppy or LS120 (sectorCount == 0x3c300)
507
+ var sectorCount = 0;
508
+ if (dev == 0xA0) {
509
+ if (obj.floppy != null) { sectorCount = (obj.floppy.size >> 9); }
510
+ } else {
511
+ if (obj.cdrom != null) { sectorCount = (obj.cdrom.size >> 11); }
512
+ }
513
+
514
+ switch (cdb[2] & 0x3f) {
515
+ case 0x01: if (dev == 0xA0) { r = (sectorCount <= 0xb40)?IDE_ModeSence_FloppyError_Recovery_Array:IDE_ModeSence_Ls120Error_Recovery_Array; } else { r = IDE_ModeSence_CDError_Recovery_Array; } break;
516
+ case 0x05: if (dev == 0xA0) { r = (sectorCount <= 0xb40)?IDE_ModeSence_FloppyDisk_Page_Array:IDE_ModeSence_LS120Disk_Page_Array; } break;
517
+ case 0x3f: if (dev == 0xA0) { r = (sectorCount <= 0xb40)?IDE_ModeSence_3F_Floppy_Array:IDE_ModeSence_3F_LS120_Array; } else { r = IDE_ModeSence_3F_CD_Array; } break;
518
+ case 0x1A: if (dev == 0xB0) { r = IDE_ModeSence_CD_1A_Array; } break;
519
+ case 0x1D: if (dev == 0xB0) { r = IDE_ModeSence_CD_1D_Array; } break;
520
+ case 0x2A: if (dev == 0xB0) { r = IDE_ModeSence_CD_2A_Array; } break;
521
+ }
522
+
523
+ if (r == null) {
524
+ obj.SendCommandEndResponse(0, 0x05, dev, 0x20, 0x00); // TODO: Send proper error!!!
525
+ } else {
526
+ // Set disk to read only (we don't support write).
527
+ //ms_data[3] = ms_data[3] | 0x80;
528
+ obj.SendDataToHost(dev, true, r, featureRegister & 1);
529
+ }
530
+ break;
531
+ default: // UNKNOWN COMMAND
532
+ if (obj.debug) console.log("IDER: Unknown SCSI command", cdb[0]);
533
+ obj.SendCommandEndResponse(0, 0x05, dev, 0x20, 0x00);
534
+ return -1;
535
+ }
536
+ return 0;
537
+ }
538
+
539
+ function sendDiskData(dev, lba, len, featureRegister) {
540
+ var media = null;
541
+ var mediaBlocks = 0;
542
+ if (dev == 0xA0) { media = obj.floppy; if (obj.floppy != null) { mediaBlocks = (obj.floppy.size >> 9); } }
543
+ if (dev == 0xB0) { media = obj.cdrom; if (obj.cdrom != null) { mediaBlocks = (obj.cdrom.size >> 11); } }
544
+ if ((len < 0) || (lba + len > mediaBlocks)) { obj.SendCommandEndResponse(1, 0x05, dev, 0x21, 0x00); return 0; }
545
+ if (len == 0) { obj.SendCommandEndResponse(1, 0x00, dev, 0x00, 0x00); return 0; }
546
+ if (media != null) {
547
+ // Send sector stats
548
+ if (obj.sectorStats) { obj.sectorStats(1, (dev == 0xA0) ? 0 : 1, mediaBlocks, lba, len); }
549
+ if (dev == 0xA0) { lba <<= 9; len <<= 9; } else { lba <<= 11; len <<= 11; }
550
+ if (g_media !== null) {
551
+ // Queue read operation
552
+ g_readQueue.push({ media: media, dev: dev, lba: lba, len: len, fr: featureRegister });
553
+ } else {
554
+ // obj.iderinfo.readbfr // TODO: MaxRead
555
+ g_media = media;
556
+ g_dev = dev;
557
+ g_lba = lba;
558
+ g_len = len;
559
+ sendDiskDataEx(featureRegister);
560
+ }
561
+ }
562
+ }
563
+
564
+ var g_readQueue = [];
565
+ var g_reset = false;
566
+ var g_media = null;
567
+ var g_dev;
568
+ var g_lba;
569
+ var g_len;
570
+ function sendDiskDataEx(featureRegister) {
571
+ var len = g_len, lba = g_lba;
572
+ if (g_len > obj.iderinfo.readbfr) { len = obj.iderinfo.readbfr; }
573
+ g_len -= len;
574
+ g_lba += len;
575
+
576
+ //console.log('Read from ' + lba + ' to ' + (lba + len) + ', total of ' + len);
577
+
578
+ var result = new Buffer(len);
579
+ fs.readSync(g_media.file, result, 0, len, lba);
580
+ obj.SendDataToHost(g_dev, (g_len == 0), result, featureRegister & 1);
581
+ if ((g_len > 0) && (g_reset == false)) {
582
+ sendDiskDataEx(featureRegister);
583
+ } else {
584
+ g_media = null;
585
+ if (g_reset) { obj.SendCommand(0x47); g_readQueue = []; g_reset = false; } // Send ResetOccuredResponse
586
+ else if (g_readQueue.length > 0) { var op = g_readQueue.shift(); g_media = op.media; g_dev = op.dev; g_lba = op.lba; g_len = op.len; sendDiskDataEx(op.fr); } // Un-queue read operation
587
+ }
588
+ }
589
+
590
+ return obj;
591
+}
592
+
593
+function ShortToStr(v) { return new Buffer([(v >> 8) & 0xFF, v & 0xFF]); }
594
+function ShortToStrX(v) { return new Buffer([v & 0xFF, (v >> 8) & 0xFF]); }
595
+function IntToStr(v) { return new Buffer([(v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF]); }
596
+function IntToStrX(v) { return new Buffer([v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF]); }
597
+function ReadShort(v, p) { return (v[p] << 8) + v[p + 1]; }
598
+function ReadShortX(v, p) { return (v[p + 1] << 8) + v[p]; }
599
+function ReadInt(v, p) { return (v[p] * 0x1000000) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
600
+function ReadSInt(v, p) { return (v[p] << 24) + (v[p + 1] << 16) + (v[p + 2] << 8) + v[p + 3]; }
601
+function ReadIntX(v, p) { return (v[p + 3] * 0x1000000) + (v[p + 2] << 16) + (v[p + 1] << 8) + v[p]; }
\ No newline at end of file
agents/modules_meshcmd/amt-redir-duk.js
new
+308
@@ -0,0 +1,308 @@
1
+/**
2
+* @description Intel AMT Redirection Transport Module - using Node
3
+* @author Ylian Saint-Hilaire
4
+* @version v0.0.1f
5
+*/
6
+
7
+// Construct a MeshServer object
8
+module.exports = function CreateAmtRedirect(module) {
9
+ var obj = {};
10
+ obj.m = module; // This is the inner module (Terminal or Desktop)
11
+ module.parent = obj;
12
+ obj.State = 0;
13
+ obj.net = require('net');
14
+ obj.tls = require('tls');
15
+ obj.socket = null;
16
+ obj.host = null;
17
+ obj.port = 0;
18
+ obj.user = null;
19
+ obj.pass = null;
20
+ obj.connectstate = 0;
21
+ obj.protocol = module.protocol; // 1 = SOL, 2 = KVM, 3 = IDER
22
+ obj.xtlsoptions = null;
23
+
24
+ obj.amtaccumulator = null;
25
+ obj.amtsequence = 1;
26
+ obj.amtkeepalivetimer = null;
27
+ obj.authuri = "/RedirectionService";
28
+ obj.digestRealmMatch = null;
29
+
30
+ obj.onStateChanged = null;
31
+
32
+ // Private method
33
+ obj.Debug = function (msg) { console.log(msg); }
34
+ var urlvars = null;
35
+
36
+ obj.Start = function (host, port, user, pass, tls, tlsFingerprint, tlsoptions) {
37
+ obj.host = host;
38
+ obj.port = port;
39
+ obj.user = user;
40
+ obj.pass = pass;
41
+ obj.xtls = tls;
42
+ obj.xtlsoptions = tlsoptions;
43
+ obj.xtlsFingerprint = tlsFingerprint;
44
+ obj.connectstate = 0;
45
+
46
+ if (tls == true) {
47
+ obj.socket = obj.tls.connect({ host: host, port: port, rejectUnauthorized: false, checkServerIdentity: obj.onCheckServerIdentity }, obj.xxOnSocketConnected);
48
+ } else {
49
+ obj.socket = obj.net.createConnection({ host: host, port: port }, obj.xxOnSocketConnected);
50
+ }
51
+ obj.socket.on('data', obj.xxOnSocketData);
52
+ obj.socket.on('close', obj.xxOnSocketClosed);
53
+ obj.socket.on('error', obj.xxOnSocketClosed);
54
+ obj.xxStateChange(1);
55
+ }
56
+
57
+ // Get the certificate of Intel AMT
58
+ //obj.getPeerCertificate = function () { if (obj.xtls == true) { return obj.socket.getPeerCertificate(); } return null; }
59
+
60
+ obj.onCheckServerIdentity = function (cert) {
61
+ var f = cert[0].fingerprint.split(':').join('').toLowerCase();
62
+ if ((obj.xtlsFingerprint != null) && (obj.xtlsFingerprint != f)) {
63
+ console.log('Invalid TLS Cert, SHA384: ' + f);
64
+ process.exit(2);
65
+ return;
66
+ } else {
67
+ if (obj.xtlsFingerprint == null) {
68
+ obj.xtlsFingerprint = f;
69
+ console.log('TLS Cert SHA384: ' + f);
70
+ }
71
+ }
72
+ }
73
+
74
+ obj.xxOnSocketConnected = function () {
75
+ if (obj.socket == null) return;
76
+ /*
77
+ if (obj.xtls == true) {
78
+ obj.xtlsCertificate = obj.socket.getPeerCertificate();
79
+ if ((obj.xtlsFingerprint != 0) && (obj.xtlsCertificate.fingerprint.split(':').join('').toLowerCase() != obj.xtlsFingerprint)) { obj.Stop(); return; }
80
+ }
81
+ */
82
+
83
+ if (urlvars && urlvars['redirtrace']) { console.log("REDIR-CONNECTED"); }
84
+ //obj.Debug("Socket Connected");
85
+ obj.xxStateChange(2);
86
+ if (obj.protocol == 1) obj.xxSend(obj.RedirectStartSol); // TODO: Put these strings in higher level module to tighten code
87
+ else if (obj.protocol == 2) obj.xxSend(obj.RedirectStartKvm); // Don't need these is the feature if not compiled-in.
88
+ else if (obj.protocol == 3) obj.xxSend(obj.RedirectStartIder);
89
+ }
90
+
91
+ obj.xxOnSocketData = function (data) {
92
+ //console.log('xxOnSocketData: ' + data.toString('hex'), data.length);
93
+ if (!data || obj.connectstate == -1) return;
94
+ if (urlvars && urlvars['redirtrace']) { console.log("REDIR-RECV(" + data.length + "): " + data.toString('hex')); }
95
+ //obj.Debug("Recv(" + data.length + "): " + rstr2hex(data));
96
+ if ((obj.protocol == 2 || obj.protocol == 3) && obj.connectstate == 1) { return obj.m.ProcessData(data); } // KVM or IDER traffic, forward it directly.
97
+ if (obj.amtaccumulator == null) { obj.amtaccumulator = data; } else { obj.amtaccumulator = Buffer.concat(obj.amtaccumulator, data); }
98
+ //obj.Debug("Recv(" + obj.amtaccumulator.length + "): " + rstr2hex(obj.amtaccumulator));
99
+ while (obj.amtaccumulator != null) {
100
+ var cmdsize = 0;
101
+ //console.log('CMD: ' + obj.amtaccumulator[0]);
102
+ switch (obj.amtaccumulator[0]) {
103
+ case 0x11: // StartRedirectionSessionReply (17)
104
+ if (obj.amtaccumulator.length < 4) return;
105
+ var statuscode = obj.amtaccumulator[1];
106
+ switch (statuscode) {
107
+ case 0: // STATUS_SUCCESS
108
+ if (obj.amtaccumulator.length < 13) return;
109
+ var oemlen = obj.amtaccumulator[12];
110
+ if (obj.amtaccumulator.length < 13 + oemlen) return;
111
+ obj.xxSend(String.fromCharCode(0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)); // Query authentication support
112
+ cmdsize = (13 + oemlen);
113
+ break;
114
+ default:
115
+ obj.Stop();
116
+ break;
117
+ }
118
+ break;
119
+ case 0x14: // AuthenticateSessionReply (20)
120
+ if (obj.amtaccumulator.length < 9) return;
121
+ var authDataLen = obj.amtaccumulator.readInt32LE(5);
122
+ if (obj.amtaccumulator.length < 9 + authDataLen) return;
123
+ var status = obj.amtaccumulator[1];
124
+ var authType = obj.amtaccumulator[4];
125
+ var authData = [];
126
+ for (i = 0; i < authDataLen; i++) { authData.push(obj.amtaccumulator[9 + i]); }
127
+ var authDataBuf = obj.amtaccumulator.slice(9, 9 + authDataLen);
128
+ cmdsize = 9 + authDataLen;
129
+ if (authType == 0) {
130
+ // Query
131
+ if (authData.indexOf(4) >= 0) {
132
+ // Good Digest Auth (With cnonce and all)
133
+ 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));
134
+ }
135
+ else if (authData.indexOf(3) >= 0) {
136
+ // Bad Digest Auth (Not sure why this is supported, cnonce is not used!)
137
+ 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));
138
+ }
139
+ else if (authData.indexOf(1) >= 0) {
140
+ // Basic Auth (Probably a good idea to not support this unless this is an old version of Intel AMT)
141
+ 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);
142
+ }
143
+ else obj.Stop();
144
+ }
145
+ else if ((authType == 3 || authType == 4) && status == 1) {
146
+ var curptr = 0;
147
+
148
+ // Realm
149
+ var realmlen = authDataBuf[curptr];
150
+ var realm = authDataBuf.slice(curptr + 1, curptr + 1 + realmlen).toString();
151
+ curptr += (realmlen + 1);
152
+
153
+ // Check the digest realm. If it does not match, close the connection.
154
+ if (obj.digestRealmMatch && (obj.digestRealmMatch != realm)) { obj.Stop(); return; }
155
+
156
+ // Nonce
157
+ var noncelen = authDataBuf[curptr];
158
+ var nonce = authDataBuf.slice(curptr + 1, curptr + 1 + noncelen).toString();
159
+ curptr += (noncelen + 1);
160
+
161
+ // QOP
162
+ var qoplen = 0;
163
+ var qop = null;
164
+ var cnonce = obj.xxRandomValueHex(32);
165
+ var snc = '00000002';
166
+ var extra = '';
167
+ if (authType == 4) {
168
+ qoplen = authDataBuf[curptr];
169
+ qop = authDataBuf.slice(curptr + 1, curptr + 1 + qoplen).toString();
170
+ curptr += (qoplen + 1);
171
+ extra = snc + ":" + cnonce + ":" + qop + ":";
172
+ }
173
+ var digest = hex_md5(hex_md5(obj.user + ":" + realm + ":" + obj.pass) + ":" + nonce + ":" + extra + hex_md5("POST:" + obj.authuri));
174
+ var totallen = obj.user.length + realm.length + nonce.length + obj.authuri.length + cnonce.length + snc.length + digest.length + 7;
175
+ if (authType == 4) totallen += (qop.length + 1);
176
+ var buf = Buffer.concat([new Buffer([0x13, 0x00, 0x00, 0x00, authType]), new Buffer([totallen & 0xFF, (totallen >> 8) & 0xFF, 0x00, 0x00]), new Buffer([obj.user.length]), new Buffer(obj.user), new Buffer([realm.length]), new Buffer(realm), new Buffer([nonce.length]), new Buffer(nonce), new Buffer([obj.authuri.length]), new Buffer(obj.authuri), new Buffer([cnonce.length]), new Buffer(cnonce), new Buffer([snc.length]), new Buffer(snc), new Buffer([digest.length]), new Buffer(digest)]);
177
+ if (authType == 4) buf = Buffer.concat([ buf, new Buffer([qop.length]), new Buffer(qop) ]);
178
+ obj.xxSend(buf);
179
+ }
180
+ else if (status == 0) { // Success
181
+ if (obj.protocol == 1) {
182
+ /*
183
+ // Serial-over-LAN: Send Intel AMT serial settings...
184
+ var MaxTxBuffer = 10000;
185
+ var TxTimeout = 100;
186
+ var TxOverflowTimeout = 0;
187
+ var RxTimeout = 10000;
188
+ var RxFlushTimeout = 100;
189
+ var Heartbeat = 0;//5000;
190
+ obj.xxSend(String.fromCharCode(0x20, 0x00, 0x00, 0x00) + ToIntStr(obj.amtsequence++) + ToShortStr(MaxTxBuffer) + ToShortStr(TxTimeout) + ToShortStr(TxOverflowTimeout) + ToShortStr(RxTimeout) + ToShortStr(RxFlushTimeout) + ToShortStr(Heartbeat) + ToIntStr(0));
191
+ */
192
+ }
193
+ if (obj.protocol == 2) {
194
+ // Remote Desktop: Send traffic directly...
195
+ obj.xxSend(new Buffer([0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
196
+ }
197
+ if (obj.protocol == 3) {
198
+ // Remote IDER: Send traffic directly...
199
+ obj.connectstate = 1;
200
+ obj.xxStateChange(3);
201
+ }
202
+ } else obj.Stop();
203
+ break;
204
+ case 0x21: // Response to settings (33)
205
+ if (obj.amtaccumulator.length < 23) break;
206
+ cmdsize = 23;
207
+ obj.xxSend(String.fromCharCode(0x27, 0x00, 0x00, 0x00) + ToIntStr(obj.amtsequence++) + String.fromCharCode(0x00, 0x00, 0x1B, 0x00, 0x00, 0x00));
208
+ if (obj.protocol == 1) { obj.amtkeepalivetimer = setInterval(obj.xxSendAmtKeepAlive, 2000); }
209
+ obj.connectstate = 1;
210
+ obj.xxStateChange(3);
211
+ break;
212
+ case 0x29: // Serial Settings (41)
213
+ if (obj.amtaccumulator.length < 10) break;
214
+ cmdsize = 10;
215
+ break;
216
+ case 0x2A: // Incoming display data (42)
217
+ if (obj.amtaccumulator.length < 10) break;
218
+ var cs = (10 + ((obj.amtaccumulator[9] & 0xFF) << 8) + (obj.amtaccumulator[8] & 0xFF));
219
+ if (obj.amtaccumulator.length < cs) break;
220
+ obj.m.ProcessData(obj.amtaccumulator.substring(10, cs));
221
+ cmdsize = cs;
222
+ break;
223
+ case 0x2B: // Keep alive message (43)
224
+ if (obj.amtaccumulator.length < 8) break;
225
+ cmdsize = 8;
226
+ break;
227
+ case 0x41:
228
+ if (obj.amtaccumulator.length < 8) break;
229
+ obj.connectstate = 1;
230
+ obj.m.Start();
231
+ // KVM traffic, forward rest of accumulator directly.
232
+ if (obj.amtaccumulator.length > 8) { obj.m.ProcessData(obj.amtaccumulator.substring(8)); }
233
+ cmdsize = obj.amtaccumulator.length;
234
+ break;
235
+ default:
236
+ console.log("Unknown Intel AMT command: " + obj.amtaccumulator[0] + " acclen=" + obj.amtaccumulator.length);
237
+ obj.Stop();
238
+ return;
239
+ }
240
+ if (cmdsize == 0) return;
241
+ if (cmdsize == obj.amtaccumulator.length) { obj.amtaccumulator = null; } else { obj.amtaccumulator = obj.amtaccumulator.slice(cmdsize); }
242
+ }
243
+ }
244
+
245
+ obj.xxSend = function (x) {
246
+ if (urlvars && urlvars['redirtrace']) { console.log("REDIR-SEND(" + x.length + "): " + rstr2hex(x)); }
247
+ //obj.Debug("Send(" + x.length + "): " + new Buffer(x, "binary").toString('hex'));
248
+ if (typeof x == 'string') { obj.socket.write(new Buffer(x, "binary")); } else { obj.socket.write(x); }
249
+ }
250
+
251
+ obj.Send = function (x) {
252
+ if (obj.socket == null || obj.connectstate != 1) return;
253
+ if (obj.protocol == 1) { obj.xxSend(String.fromCharCode(0x28, 0x00, 0x00, 0x00) + ToIntStr(obj.amtsequence++) + ToShortStr(x.length) + x); } else { obj.xxSend(x); }
254
+ }
255
+
256
+ obj.xxSendAmtKeepAlive = function () {
257
+ if (obj.socket == null) return;
258
+ obj.xxSend(String.fromCharCode(0x2B, 0x00, 0x00, 0x00) + ToIntStr(obj.amtsequence++));
259
+ }
260
+
261
+ // Uses OpenSSL random to generate a hex string
262
+ obj.xxRandomValueHex = function (len) {
263
+ var t = [], l = Math.floor(len / 2);
264
+ for (var i = 0; i < l; i++) { t.push(obj.tls.generateRandomInteger("0", "255")); }
265
+ return new Buffer(t).toString('hex');
266
+ }
267
+
268
+ obj.xxOnSocketClosed = function () {
269
+ obj.socket = null;
270
+ if (urlvars && urlvars['redirtrace']) { console.log("REDIR-CLOSED"); }
271
+ //obj.Debug("Socket Closed");
272
+ obj.Stop();
273
+ }
274
+
275
+ obj.xxStateChange = function(newstate) {
276
+ if (obj.State == newstate) return;
277
+ obj.State = newstate;
278
+ obj.m.xxStateChange(obj.State);
279
+ if (obj.onStateChanged != null) obj.onStateChanged(obj, obj.State);
280
+ }
281
+
282
+ obj.Stop = function () {
283
+ if (urlvars && urlvars['redirtrace']) { console.log("REDIR-CLOSED"); }
284
+ //obj.Debug("Socket Stopped");
285
+ obj.xxStateChange(0);
286
+ obj.connectstate = -1;
287
+ obj.amtaccumulator = "";
288
+ if (obj.socket != null) { obj.socket.destroy(); obj.socket = null; }
289
+ if (obj.amtkeepalivetimer != null) { clearInterval(obj.amtkeepalivetimer); obj.amtkeepalivetimer = null; }
290
+ }
291
+
292
+ obj.RedirectStartSol = new Buffer([0x10, 0x00, 0x00, 0x00, 0x53, 0x4F, 0x4C, 0x20]);
293
+ obj.RedirectStartKvm = new Buffer([0x10, 0x01, 0x00, 0x00, 0x4b, 0x56, 0x4d, 0x52]);
294
+ obj.RedirectStartIder = new Buffer([0x10, 0x00, 0x00, 0x00, 0x49, 0x44, 0x45, 0x52]);
295
+
296
+ return obj;
297
+}
298
+
299
+function ToIntStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF), ((v >> 16) & 0xFF), ((v >> 24) & 0xFF)); }
300
+function ToShortStr(v) { return String.fromCharCode((v & 0xFF), ((v >> 8) & 0xFF)); }
301
+
302
+function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
303
+function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
304
+function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
305
+function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
306
+
307
+var md5hasher = require('MD5Stream').create();
308
+function hex_md5(a) { return md5hasher.syncHash(a).toString('hex').toLowerCase(); }
\ No newline at end of file
agents/modules_meshcmd_min/amt-ider.min.js
new
+1
@@ -0,0 +1 @@
1
+module.exports=function CreateAmtRemoteIder(){var B={};B.protocol=3;B.bytesToAmt=0;B.bytesFromAmt=0;B.rx_timeout=30000;B.tx_timeout=0;B.heartbeat=20000;B.version=1;B.acc=null;B.inSequence=0;B.outSequence=0;B.iderinfo=null;B.enabled=false;B.iderStart=0;B.floppy=null;B.cdrom=null;B.floppyReady=false;B.cdromReady=false;B.sectorStats=null;B.debug=false;var z=new Buffer([0,38,49,128,0,0,0,0,5,30,16,169,8,32,2,0,3,195,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0]);var s=new Buffer([0,92,36,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0,3,22,0,160,0,0,0,0,0,18,2,0,0,0,0,0,0,0,160,0,0,0,5,30,16,169,8,32,2,0,3,195,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0,8,10,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,17,36,49]);var x=new Buffer([0,38,36,128,0,0,0,0,5,30,4,176,2,18,2,0,0,80,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0]);var r=new Buffer([0,92,36,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0,3,22,0,160,0,0,0,0,0,18,2,0,0,0,0,0,0,0,160,0,0,0,5,30,4,176,2,18,2,0,0,80,0,0,0,0,0,0,0,0,0,0,40,0,0,0,0,0,0,0,2,208,0,0,8,10,0,0,0,0,0,0,0,0,0,0,11,6,0,0,0,17,36,49]);var t=new Buffer([0,18,1,128,0,0,0,0,26,10,0,0,0,0,0,0,0,0,0,0]);var u=new Buffer([0,18,1,128,0,0,0,0,29,10,0,0,0,0,0,0,0,0,0,0]);var v=new Buffer([0,32,1,128,0,0,0,0,42,24,0,0,0,0,32,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0]);var q=new Buffer([0,40,1,128,0,0,0,0,1,6,0,255,0,0,0,0,42,24,0,0,0,0,2,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0]);var i=new Buffer([0,0,0,40,0,0,0,8]);var j=new Buffer([0,0,3,4,0,8,1,0]);var h=new Buffer([0,1,3,4,0,0,0,2]);var m=new Buffer([0,2,3,4,0,0,0,0]);var l=new Buffer([0,3,3,4,41,0,0,2]);var k=new Buffer([0,16,1,8,0,0,8,0,0,1,0,0]);var o=new Buffer([0,30,3,0]);var n=new Buffer([1,0,3,0]);var p=new Buffer([1,5,3,0]);var y=new Buffer([0,18,36,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0]);var A=new Buffer([0,18,49,128,0,0,0,0,1,10,0,1,0,0,0,0,2,0,0,0]);var w=new Buffer([0,14,1,128,0,0,0,0,1,6,0,255,0,0,0,0]);B.xxStateChange=function(E){if(B.debug){console.log("IDER-StateChange",E)}if(E==0){B.Stop()}if(E==3){B.Start()}};B.Start=function(){if(B.debug){console.log("IDER-Start");console.log(B.floppy,B.cdrom)}B.bytesToAmt=0;B.bytesFromAmt=0;B.inSequence=0;B.outSequence=0;e=[];B.SendCommand(64,Buffer.concat([ShortToStrX(B.rx_timeout),ShortToStrX(B.tx_timeout),ShortToStrX(B.heartbeat),IntToStrX(B.version)]));if(B.sectorStats){B.sectorStats(0,0,B.floppy?(B.floppy.size>>9):0);B.sectorStats(0,1,B.cdrom?(B.cdrom.size>>11):0)}};B.Stop=function(){if(B.debug){console.log("IDER-Stop")}B.parent.Stop()};B.ProcessData=function(E){B.bytesFromAmt+=E.length;if(B.acc==null){B.acc=E}else{B.acc=Buffer.concat(B.acc,E)}if(B.debug){console.log("IDER-ProcessData",B.acc.length,B.acc.toString("hex"))}while(B.acc!=null){var F=B.ProcessDataEx();if(F==0){return}if(B.inSequence!=ReadIntX(B.acc,4)){if(B.debug){console.log("ERROR: Out of sequence",B.inSequence,ReadIntX(B.acc,4))}B.Stop();return}B.inSequence++;if(F==B.acc.length){B.acc=null}else{B.acc=B.acc.slice(F)}}};B.SendCommand=function(F,H,G,I){if(H==null){H=new Buffer(0)}var E=((F>50)&&(G==true))?2:0;if(I){E+=1}var J=Buffer.concat([Buffer([F,0,0,E]),IntToStrX(B.outSequence++),H]);B.parent.xxSend(J);B.bytesToAmt+=J.length};B.SendCommandEndResponse=function(H,I,G,E,F){if(H){B.SendCommand(81,new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,197,0,3,0,0,0,G,80,0,0,0]),true)}else{B.SendCommand(81,new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,135,(I<<4),3,0,0,0,G,81,I,E,F]),true)}};B.SendDataToHost=function(G,E,F,H){var I=(H)?0:F.length;if(E==true){B.SendCommand(84,Buffer.concat([new Buffer([0,(F.length&255),(F.length>>8),0,H?180:181,0,2,0,(I&255),(I>>8),G,88,133,0,3,0,0,0,G,80,0,0,0,0,0,0]),F]),E,H)}else{B.SendCommand(84,Buffer.concat([new Buffer([0,(F.length&255),(F.length>>8),0,H?180:181,0,2,0,(I&255),(I>>8),G,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),F]),E,H)}};B.SendGetDataFromHost=function(F,E){B.SendCommand(82,new Buffer([0,(E&255),(E>>8),0,181,0,0,0,(E&255),(E>>8),F,88,0,0,0,0,0,0,0,0,0,0,0]),false)};B.SendDisableEnableFeatures=function(F,E){if(E==null){E=""}B.SendCommand(72,Buffer.concat([new Buffer([F]),E]))};B.ProcessDataEx=function(){if(B.acc.length<8){return 0}switch(B.acc[0]){case 65:if(B.acc.length<30){return 0}var I=B.acc[29];if(B.acc.length<(30+I)){return 0}B.iderinfo={};B.iderinfo.major=B.acc[8];B.iderinfo.minor=B.acc[9];B.iderinfo.fwmajor=B.acc[10];B.iderinfo.fwminor=B.acc[11];B.iderinfo.readbfr=ReadShortX(B.acc,16);B.iderinfo.writebfr=ReadShortX(B.acc,18);B.iderinfo.proto=B.acc[21];B.iderinfo.iana=ReadIntX(B.acc,25);if(B.debug){console.log(B.iderinfo)}if(B.iderinfo.proto!=0){if(B.debug){console.log("Unknown proto",B.iderinfo.proto)}B.Stop()}if(B.iderinfo.readbfr>8192){if(B.debug){console.log("Illegal read buffer size",B.iderinfo.readbfr)}B.Stop()}if(B.iderinfo.writebfr>8192){if(B.debug){console.log("Illegal write buffer size",B.iderinfo.writebfr)}B.Stop()}if(B.iderStart==0){B.SendDisableEnableFeatures(3,IntToStrX(1+8))}else{if(B.iderStart==1){B.SendDisableEnableFeatures(3,IntToStrX(1+16))}else{if(B.iderStart==2){B.SendDisableEnableFeatures(3,IntToStrX(1+24))}}}return 30+I;case 67:if(B.debug){console.log("CLOSE")}B.Stop();return 8;case 68:B.SendCommand(69);return 8;case 69:if(B.debug){console.log("PONG")}return 8;case 70:if(B.acc.length<9){return 0}var J=B.acc[8];if(d===null){B.SendCommand(71);if(B.debug){console.log("RESETOCCURED1",J)}}else{f=true;if(B.debug){console.log("RESETOCCURED2",J)}}return 9;case 73:if(B.acc.length<13){return 0}var K=B.acc[8];var L=ReadIntX(B.acc,9);if(B.debug){console.log("STATUS_DATA",K,L)}switch(K){case 1:if(L&1){if(B.iderStart==0){B.SendDisableEnableFeatures(3,IntToStrX(1+8))}else{if(B.iderStart==1){B.SendDisableEnableFeatures(3,IntToStrX(1+16))}else{if(B.iderStart==2){B.SendDisableEnableFeatures(3,IntToStrX(1+24))}}}}break;case 2:B.enabled=(L&2)?true:false;if(B.debug){console.log("IDER Status: "+B.enabled)}break;case 3:if(L!=1){if(B.debug){console.log("Register toggle failure")}}break}return 13;case 74:if(B.acc.length<11){return 0}if(B.debug){console.log("IDER: ABORT",B.acc[8])}return 11;case 75:return 8;case 80:if(B.acc.length<28){return 0}var F=(B.acc[14]&16)?176:160;var G=B.acc[14];var E=B.acc.slice(16,28);var H=B.acc[9];if(B.debug){console.log("SCSI_CMD",F,E.toString("hex"),H,G)}g(F,E,H,G);return 28;case 83:if(B.acc.length<14){return 0}var I=ReadShortX(B.acc,9);if(B.acc.length<(14+I)){return 0}if(B.debug){console.log("SCSI_WRITE, len = "+(14+I))}B.SendCommand(81,new Buffer([0,0,0,0,0,0,0,0,0,0,0,0,135,112,3,0,0,0,160,81,7,39,0]),true);return 14+I;default:if(B.debug){console.log("Unknown IDER command",B.acc[0])}B.Stop();break}return 0};function g(I,H,K,J){var N;var O;switch(H[0]){case 0:if(B.debug){console.log("SCSI: TEST_UNIT_READY",I)}switch(I){case 160:if(B.floppy==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}if(B.floppyReady==false){B.floppyReady=true;B.SendCommandEndResponse(1,6,I,40,0);return -1}break;case 176:if(B.cdrom==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}if(B.cdromReady==false){B.cdromReady=true;B.SendCommandEndResponse(1,6,I,40,0);return -1}break;default:if(B.debug){console.log("SCSI Internal error 3",I)}return -1}B.SendCommandEndResponse(1,0,I,0,0);break;case 8:N=((H[1]&31)<<16)+(H[2]<<8)+H[3];O=H[4];if(O==0){O=256}if(B.debug){console.log("SCSI: READ_6",I,N,O)}C(I,N,O,K);break;case 10:N=((H[1]&31)<<16)+(H[2]<<8)+H[3];O=H[4];if(O==0){O=256}if(B.debug){console.log("SCSI: WRITE_6",I,N,O)}B.SendCommandEndResponse(1,2,I,58,0);return -1;case 26:if(B.debug){console.log("SCSI: MODE_SENSE_6",I)}if((H[2]==63)&&(H[3]==0)){var E=0,F=0;switch(I){case 160:if(B.floppy==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}E=0;F=128;break;case 176:if(B.cdrom==null){B.SendCommandEndResponse(1,2,I,58,0);return -1}E=5;F=128;break;default:if(B.debug){console.log("SCSI Internal error 6",I)}return -1}B.SendDataToHost(I,true,new Buffer([0,E,F,0]),K&1);return}B.SendCommandEndResponse(1,5,I,36,0);break;case 27:B.SendCommandEndResponse(1,0,I);break;case 30:if(B.debug){console.log("SCSI: ALLOW_MEDIUM_REMOVAL",I)}if((I==160)&&(B.floppy==null)){B.SendCommandEndResponse(1,2,I,58,0);return -1}if((I==176)&&(B.cdrom==null)){B.SendCommandEndResponse(1,2,I,58,0);return -1}B.SendCommandEndResponse(1,0,I,0,0);break;case 35:if(B.debug){console.log("SCSI: READ_FORMAT_CAPACITIES",I)}var G=ReadShort(H,7);var Q=0,V;var P=G/8;switch(I){case 160:if((B.floppy==null)||(B.floppy.size==0)){B.SendCommandEndResponse(0,5,I,36,0);return -1}V=(B.floppy.size>>9)-1;break;case 176:if((B.cdrom==null)||(B.cdrom.size==0)){B.SendCommandEndResponse(0,5,I,36,0);return -1}V=(B.cdrom.size>>11)-1;break;default:if(B.debug){console.log("SCSI Internal error 4",I)}return -1}B.SendDataToHost(I,true,Buffer.concat([IntToStr(8),new Buffer([0,0,11,64,2,0,2,0])]),K&1);break;case 37:if(B.debug){console.log("SCSI: READ_CAPACITY",I)}var O=0;switch(I){case 160:if((B.floppy==null)||(B.floppy.size==0)){B.SendCommandEndResponse(0,2,I,58,0);return -1}if(B.floppy!=null){O=(B.floppy.size>>9)-1}if(B.debug){console.log("DEV_FLOPPY",O)}break;case 176:if((B.cdrom==null)||(B.cdrom.size==0)){B.SendCommandEndResponse(0,2,I,58,0);return -1}if(B.cdrom!=null){O=(B.cdrom.size>>11)-1}if(B.debug){console.log("DEV_CDDVD",O)}break;default:if(B.debug){console.log("SCSI Internal error 4",I)}return -1}if(B.debug){console.log("SCSI: READ_CAPACITY2",I,J)}B.SendDataToHost(J,true,Buffer.concat([IntToStr(O),new Buffer([0,0,((I==176)?8:2),0])]),K&1);break;case 40:N=ReadInt(H,2);O=ReadShort(H,7);if(B.debug){console.log("SCSI: READ_10",I,N,O)}C(I,N,O,K);break;case 42:case 46:N=ReadInt(H,2);O=ReadShort(H,7);if(B.debug){console.log("SCSI: WRITE_10",I,N,O)}B.SendGetDataFromHost(I,512*O);break;case 67:var G=ReadShort(H,7);var R=H[1]&2;var M=H[2]&7;if(M==0){M=H[9]>>6}if(B.debug){console.log("SCSI: READ_TOC, dev="+I+", buflen="+G+", msf="+R+", format="+M)}switch(I){case 160:B.SendCommandEndResponse(1,5,I,32,0);return -1;case 176:break;default:if(B.debug){console.log("SCSI Internal error 9",I)}return -1}if(M==1){B.SendDataToHost(I,true,new Buffer([0,10,1,1,0,20,1,0,0,0,0,0]),K&1)}else{if(M==0){if(R){B.SendDataToHost(I,true,new Buffer([0,18,1,1,0,20,1,0,0,0,2,0,0,20,170,0,0,0,52,19]),K&1)}else{B.SendDataToHost(I,true,new Buffer([0,18,1,1,0,20,1,0,0,0,0,0,0,20,170,0,0,0,0,0]),K&1)}}}break;case 70:var W=(H[1]!=2);var L=ReadShort(H,2);var G=ReadShort(H,7);if(B.debug){console.log("SCSI: GET_CONFIGURATION",I,W,L,G)}if(G==0){B.SendDataToHost(I,true,Buffer.concat([IntToStr(60),IntToStr(8)]),K&1);return -1}var T=null;if(L==0){T=j}if((L==1)||(W&&(L<1))){T=h}if((L==2)||(W&&(L<2))){T=m}if((L==3)||(W&&(L<3))){T=l}if((L==16)||(W&&(L<16))){T=k}if((L==30)||(W&&(L<30))){T=o}if((L==256)||(W&&(L<256))){T=n}if((L==261)||(W&&(L<261))){T=p}if(T==null){T=Buffer.concat([IntToStr(8),IntToStr(4)])}else{T=Buffer.concat([IntToStr(8),IntToStr(T.length+4),T])}if(T.length>G){T=T.slice(0,G)}B.SendDataToHost(I,true,T,K&1);return -1;case 74:if(B.debug){console.log("SCSI: GET_EVENT_STATUS_NOTIFICATION",I,H[1],H[4],H[9])}if((H[1]!=1)&&(H[4]!=16)){if(B.debug){console.log("SCSI ERROR")}B.SendCommandEndResponse(1,5,I,38,1);break}var S=0;if((I==160)&&(B.floppy!=null)){S=2}else{if((I==176)&&(B.cdrom!=null)){S=2}}B.SendDataToHost(I,true,new Buffer([0,S,128,0]),K&1);break;case 76:B.SendCommand(81,Buffer.concat([IntToStrX(0),IntToStrX(0),IntToStrX(0),new Buffer([135,80,3,0,0,0,176,81,5,32,0])]),true);break;case 81:if(B.debug){console.log("SCSI READ_DISC_INFO",I)}B.SendCommandEndResponse(0,5,I,32,0);return -1;case 85:if(B.debug){console.log("SCSI ERROR: MODE_SELECT_10",I)}B.SendCommandEndResponse(1,5,I,32,0);return -1;case 90:if(B.debug){console.log("SCSI: MODE_SENSE_10",I,H[2]&63)}var G=ReadShort(H,7);var T=null;if(G==0){B.SendDataToHost(I,true,Buffer.concat([IntToStr(60),IntToStr(8)]),K&1);return -1}var U=0;if(I==160){if(B.floppy!=null){U=(B.floppy.size>>9)}}else{if(B.cdrom!=null){U=(B.cdrom.size>>11)}}switch(H[2]&63){case 1:if(I==160){T=(U<=2880)?y:A}else{T=w}break;case 5:if(I==160){T=(U<=2880)?x:z}break;case 63:if(I==160){T=(U<=2880)?r:s}else{T=q}break;case 26:if(I==176){T=t}break;case 29:if(I==176){T=u}break;case 42:if(I==176){T=v}break}if(T==null){B.SendCommandEndResponse(0,5,I,32,0)}else{B.SendDataToHost(I,true,T,K&1)}break;default:if(B.debug){console.log("IDER: Unknown SCSI command",H[0])}B.SendCommandEndResponse(0,5,I,32,0);return -1}return 0}function C(E,G,H,F){var I=null;var J=0;if(E==160){I=B.floppy;if(B.floppy!=null){J=(B.floppy.size>>9)}}if(E==176){I=B.cdrom;if(B.cdrom!=null){J=(B.cdrom.size>>11)}}if((H<0)||(G+H>J)){B.SendCommandEndResponse(1,5,E,33,0);return 0}if(H==0){B.SendCommandEndResponse(1,0,E,0,0);return 0}if(I!=null){if(B.sectorStats){B.sectorStats(1,(E==160)?0:1,J,G,H)}if(E==160){G<<=9;H<<=9}else{G<<=11;H<<=11}if(d!==null){e.push({media:I,dev:E,lba:G,len:H,fr:F})}else{d=I;a=E;b=G;c=H;D(F)}}}var e=[];var f=false;var d=null;var a;var b;var c;function D(E){var G=c,F=b;if(c>B.iderinfo.readbfr){G=B.iderinfo.readbfr}c-=G;b+=G;var I=new Buffer(G);fs.readSync(d.file,I,0,G,F);B.SendDataToHost(a,(c==0),I,E&1);if((c>0)&&(f==false)){D(E)}else{d=null;if(f){B.SendCommand(71);e=[];f=false}else{if(e.length>0){var H=e.shift();d=H.media;a=H.dev;b=H.lba;c=H.len;D(H.fr)}}}}return B};function ShortToStr(a){return new Buffer([(a>>8)&255,a&255])}function ShortToStrX(a){return new Buffer([a&255,(a>>8)&255])}function IntToStr(a){return new Buffer([(a>>24)&255,(a>>16)&255,(a>>8)&255,a&255])}function IntToStrX(a){return new Buffer([a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255])}function ReadShort(b,a){return(b[a]<<8)+b[a+1]}function ReadShortX(b,a){return(b[a+1]<<8)+b[a]}function ReadInt(b,a){return(b[a]*16777216)+(b[a+1]<<16)+(b[a+2]<<8)+b[a+3]}function ReadSInt(b,a){return(b[a]<<24)+(b[a+1]<<16)+(b[a+2]<<8)+b[a+3]}function ReadIntX(b,a){return(b[a+3]*16777216)+(b[a+2]<<16)+(b[a+1]<<8)+b[a]};
\ No newline at end of file
agents/modules_meshcmd_min/amt-redir-duk.min.js
new
+1
@@ -0,0 +1 @@
1
+module.exports=function CreateAmtRedirect(a){var b={};b.m=a;a.parent=b;b.State=0;b.net=require("net");b.tls=require("tls");b.socket=null;b.host=null;b.port=0;b.user=null;b.pass=null;b.connectstate=0;b.protocol=a.protocol;b.xtlsoptions=null;b.amtaccumulator=null;b.amtsequence=1;b.amtkeepalivetimer=null;b.authuri="/RedirectionService";b.digestRealmMatch=null;b.onStateChanged=null;b.Debug=function(d){console.log(d)};var c=null;b.Start=function(d,f,k,e,g,h,j){b.host=d;b.port=f;b.user=k;b.pass=e;b.xtls=g;b.xtlsoptions=j;b.xtlsFingerprint=h;b.connectstate=0;if(g==true){b.socket=b.tls.connect({host:d,port:f,rejectUnauthorized:false,checkServerIdentity:b.onCheckServerIdentity},b.xxOnSocketConnected)}else{b.socket=b.net.createConnection({host:d,port:f},b.xxOnSocketConnected)}b.socket.on("data",b.xxOnSocketData);b.socket.on("close",b.xxOnSocketClosed);b.socket.on("error",b.xxOnSocketClosed);b.xxStateChange(1)};b.onCheckServerIdentity=function(d){var e=d[0].fingerprint.split(":").join("").toLowerCase();if((b.xtlsFingerprint!=null)&&(b.xtlsFingerprint!=e)){console.log("Invalid TLS Cert, SHA384: "+e);process.exit(2);return}else{if(b.xtlsFingerprint==null){b.xtlsFingerprint=e;console.log("TLS Cert SHA384: "+e)}}};b.xxOnSocketConnected=function(){if(b.socket==null){return}if(c&&c.redirtrace){console.log("REDIR-CONNECTED")}b.xxStateChange(2);if(b.protocol==1){b.xxSend(b.RedirectStartSol)}else{if(b.protocol==2){b.xxSend(b.RedirectStartKvm)}else{if(b.protocol==3){b.xxSend(b.RedirectStartIder)}}}};b.xxOnSocketData=function(n){if(!n||b.connectstate==-1){return}if(c&&c.redirtrace){console.log("REDIR-RECV("+n.length+"): "+n.toString("hex"))}if((b.protocol==2||b.protocol==3)&&b.connectstate==1){return b.m.ProcessData(n)}if(b.amtaccumulator==null){b.amtaccumulator=n}else{b.amtaccumulator=Buffer.concat(b.amtaccumulator,n)}while(b.amtaccumulator!=null){var j=0;switch(b.amtaccumulator[0]){case 17:if(b.amtaccumulator.length<4){return}var z=b.amtaccumulator[1];switch(z){case 0:if(b.amtaccumulator.length<13){return}var s=b.amtaccumulator[12];if(b.amtaccumulator.length<13+s){return}b.xxSend(String.fromCharCode(19,0,0,0,0,0,0,0,0));j=(13+s);break;default:b.Stop();break}break;case 20:if(b.amtaccumulator.length<9){return}var f=b.amtaccumulator.readInt32LE(5);if(b.amtaccumulator.length<9+f){return}var y=b.amtaccumulator[1];var g=b.amtaccumulator[4];var d=[];for(i=0;i<f;i++){d.push(b.amtaccumulator[9+i])}var e=b.amtaccumulator.slice(9,9+f);j=9+f;if(g==0){if(d.indexOf(4)>=0){b.xxSend(String.fromCharCode(19,0,0,0,4)+IntToStrX(b.user.length+b.authuri.length+8)+String.fromCharCode(b.user.length)+b.user+String.fromCharCode(0,0)+String.fromCharCode(b.authuri.length)+b.authuri+String.fromCharCode(0,0,0,0))}else{if(d.indexOf(3)>=0){b.xxSend(String.fromCharCode(19,0,0,0,3)+IntToStrX(b.user.length+b.authuri.length+7)+String.fromCharCode(b.user.length)+b.user+String.fromCharCode(0,0)+String.fromCharCode(b.authuri.length)+b.authuri+String.fromCharCode(0,0,0))}else{if(d.indexOf(1)>=0){b.xxSend(String.fromCharCode(19,0,0,0,1)+IntToStrX(b.user.length+b.pass.length+2)+String.fromCharCode(b.user.length)+b.user+String.fromCharCode(b.pass.length)+b.pass)}else{b.Stop()}}}}else{if((g==3||g==4)&&y==1){var m=0;var w=e[m];var v=e.slice(m+1,m+1+w).toString();m+=(w+1);if(b.digestRealmMatch&&(b.digestRealmMatch!=v)){b.Stop();return}var r=e[m];var q=e.slice(m+1,m+1+r).toString();m+=(r+1);var u=0;var t=null;var k=b.xxRandomValueHex(32);var x="00000002";var p="";if(g==4){u=e[m];t=e.slice(m+1,m+1+u).toString();m+=(u+1);p=x+":"+k+":"+t+":"}var o=hex_md5(hex_md5(b.user+":"+v+":"+b.pass)+":"+q+":"+p+hex_md5("POST:"+b.authuri));var A=b.user.length+v.length+q.length+b.authuri.length+k.length+x.length+o.length+7;if(g==4){A+=(t.length+1)}var h=Buffer.concat([new Buffer([19,0,0,0,g]),new Buffer([A&255,(A>>8)&255,0,0]),new Buffer([b.user.length]),new Buffer(b.user),new Buffer([v.length]),new Buffer(v),new Buffer([q.length]),new Buffer(q),new Buffer([b.authuri.length]),new Buffer(b.authuri),new Buffer([k.length]),new Buffer(k),new Buffer([x.length]),new Buffer(x),new Buffer([o.length]),new Buffer(o)]);if(g==4){h=Buffer.concat([h,new Buffer([t.length]),new Buffer(t)])}b.xxSend(h)}else{if(y==0){if(b.protocol==1){}if(b.protocol==2){b.xxSend(new Buffer([64,0,0,0,0,0,0,0]))}if(b.protocol==3){b.connectstate=1;b.xxStateChange(3)}}else{b.Stop()}}}break;case 33:if(b.amtaccumulator.length<23){break}j=23;b.xxSend(String.fromCharCode(39,0,0,0)+ToIntStr(b.amtsequence++)+String.fromCharCode(0,0,27,0,0,0));if(b.protocol==1){b.amtkeepalivetimer=setInterval(b.xxSendAmtKeepAlive,2000)}b.connectstate=1;b.xxStateChange(3);break;case 41:if(b.amtaccumulator.length<10){break}j=10;break;case 42:if(b.amtaccumulator.length<10){break}var l=(10+((b.amtaccumulator[9]&255)<<8)+(b.amtaccumulator[8]&255));if(b.amtaccumulator.length<l){break}b.m.ProcessData(b.amtaccumulator.substring(10,l));j=l;break;case 43:if(b.amtaccumulator.length<8){break}j=8;break;case 65:if(b.amtaccumulator.length<8){break}b.connectstate=1;b.m.Start();if(b.amtaccumulator.length>8){b.m.ProcessData(b.amtaccumulator.substring(8))}j=b.amtaccumulator.length;break;default:console.log("Unknown Intel AMT command: "+b.amtaccumulator[0]+" acclen="+b.amtaccumulator.length);b.Stop();return}if(j==0){return}if(j==b.amtaccumulator.length){b.amtaccumulator=null}else{b.amtaccumulator=b.amtaccumulator.slice(j)}}};b.xxSend=function(d){if(c&&c.redirtrace){console.log("REDIR-SEND("+d.length+"): "+rstr2hex(d))}if(typeof d=="string"){b.socket.write(new Buffer(d,"binary"))}else{b.socket.write(d)}};b.Send=function(d){if(b.socket==null||b.connectstate!=1){return}if(b.protocol==1){b.xxSend(String.fromCharCode(40,0,0,0)+ToIntStr(b.amtsequence++)+ToShortStr(d.length)+d)}else{b.xxSend(d)}};b.xxSendAmtKeepAlive=function(){if(b.socket==null){return}b.xxSend(String.fromCharCode(43,0,0,0)+ToIntStr(b.amtsequence++))};b.xxRandomValueHex=function(f){var g=[],e=Math.floor(f/2);for(var d=0;d<e;d++){g.push(b.tls.generateRandomInteger("0","255"))}return new Buffer(g).toString("hex")};b.xxOnSocketClosed=function(){b.socket=null;if(c&&c.redirtrace){console.log("REDIR-CLOSED")}b.Stop()};b.xxStateChange=function(d){if(b.State==d){return}b.State=d;b.m.xxStateChange(b.State);if(b.onStateChanged!=null){b.onStateChanged(b,b.State)}};b.Stop=function(){if(c&&c.redirtrace){console.log("REDIR-CLOSED")}b.xxStateChange(0);b.connectstate=-1;b.amtaccumulator="";if(b.socket!=null){b.socket.destroy();b.socket=null}if(b.amtkeepalivetimer!=null){clearInterval(b.amtkeepalivetimer);b.amtkeepalivetimer=null}};b.RedirectStartSol=new Buffer([16,0,0,0,83,79,76,32]);b.RedirectStartKvm=new Buffer([16,1,0,0,75,86,77,82]);b.RedirectStartIder=new Buffer([16,0,0,0,73,68,69,82]);return b};function ToIntStr(a){return String.fromCharCode((a&255),((a>>8)&255),((a>>16)&255),((a>>24)&255))}function ToShortStr(a){return String.fromCharCode((a&255),((a>>8)&255))}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}var md5hasher=require("MD5Stream").create();function hex_md5(b){return md5hasher.syncHash(b).toString("hex").toLowerCase()};
\ No newline at end of file
meshagent.js
+3
-3
@@ -696,7 +696,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
696
}
697
}
698
699
- completeAgentConnection3();
699
+ completeAgentConnection3(device);
700
});
701
}
702
@@ -736,10 +736,10 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
736
parent.parent.DispatchEvent(['*', obj.dbMeshKey], obj, { etype: 'node', action: 'addnode', node: device, msg: ('Added device ' + obj.agentInfo.computerName + ' to mesh ' + mesh.name), domain: domain.id });
737
}
738
739
- completeAgentConnection3();
739
+ completeAgentConnection3(device);
740
}
741
742
- function completeAgentConnection3() {
742
+ function completeAgentConnection3(device) {
743
// Check if this agent is already connected
744
const dupAgent = parent.wsagents[obj.dbNodeKey];
745
parent.wsagents[obj.dbNodeKey] = obj;
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.3.6-a",
3
+ "version": "0.3.6-b",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",