From 2820e5b341e189c20c1379c541f2b6ab2b18827c Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 21 Jul 2025 22:59:36 +0200 Subject: [PATCH] Mon 21 Jul 22:43:21 CEST 2025 --- js/dos/network.js | 1032 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1032 insertions(+) create mode 100644 js/dos/network.js diff --git a/js/dos/network.js b/js/dos/network.js new file mode 100644 index 0000000..006b5e1 --- /dev/null +++ b/js/dos/network.js @@ -0,0 +1,1032 @@ +/** + ** ============================== + ** O O O OOOO + ** O O O O O O + ** O O O O O O + ** OOOO OOOO O OOO OOOO + ** O O O O O O O + ** O O O O O O O + ** OOOO OOOO O O OOOO + ** ============================== + ** Dr. Stefan Bosse http://www.bsslab.de + ** + ** COPYRIGHT: THIS SOFTWARE, EXECUTABLE AND SOURCE CODE IS OWNED + ** BY THE AUTHOR. + ** THIS SOURCE CODE MAY NOT BE COPIED, EXTRACTED, + ** MODIFIED, OR OTHERWISE USED IN A CONTEXT + ** OUTSIDE OF THE SOFTWARE SYSTEM. + ** + ** $AUTHORS: Stefan Bosse + ** $INITIAL: (C) 2006-2018 bLAB + ** $CREATED: 3-5-15 by sbosse. + ** $VERSION: 1.2.6 + ** + ** $INFO: + ** + ** DOS: Networking, Commands, Status/Error codes, .. + ** + ** $ENDOFINFO + */ +"use strict"; +var log = 0; + +var util = Require('util'); + +var Io = Require('com/io'); +var Comp = Require('com/compat'); +var String = Comp.string; +var Array = Comp.array; +var Perv =Comp.pervasives; +var Des48 = Require('dos/des48'); +var Base64 = Require('os/base64'); +var Rand = Comp.random; +var Fs = Require('fs'); + +//var xmldoc = Require('xmldoc'); + + +function pad(str,size) { + while (str.length < (size || 2)) {str = "0" + str;} + return str; +} + + +/** Direction + * +var Direction = { + NORTH:1, + WEST:2, + EAST:3, + SOUTH:4, + ORIGIN:5, + tostring:function (i) { + switch (i) { + case 1: return 'NORTH'; + case 2: return 'WEST'; + case 3: return 'EAST'; + case 4: return 'SOUTH'; + case 5: return 'ORIGIN'; + default: return 'Direction?'; + } + } +}; +*/ + + +// Standard Object Service +var STD_FIRST_COM = 1000; +var STD_LAST_COM = 1999; +var STD_FIRST_ERR = (-STD_FIRST_COM); +var STD_LAST_ERR = (-STD_LAST_COM); + +// File Server +var AFS_FIRST_COM = 2000; +var AFS_LAST_COM = 2099; +var AFS_FIRST_ERR = (-AFS_FIRST_COM); +var AFS_LAST_ERR = (-AFS_LAST_COM); +var AFS_REQBUFSZ = 1024*32; + + +// Directory and Name Server +var DNS_FIRST_COM = 2100; +var DNS_LAST_COM = 2199; +var DNS_FIRST_ERR = (-DNS_FIRST_COM); +var DNS_LAST_ERR = (-DNS_LAST_COM); +var DNS_MAXCOLUMNS = 4; + +// System Process Server (incl. Agent Platform Manager) +var PS_FIRST_COM = 2200; +var PS_LAST_COM = 2299; +var PS_FIRST_ERR = (-PS_FIRST_COM); +var PS_LAST_ERR = (-PS_LAST_COM); + +// Broker Server +var BR_FIRST_COM = 2300; +var BR_LAST_COM = 2399; +var BR_FIRST_ERR = (-BR_FIRST_COM); +var BR_LAST_ERR = (-BR_LAST_COM); +/** RPC Status + * + * @enum {number} + */ +var Status = { + STD_OK:0, + STD_CAPBAD : STD_FIRST_ERR, + STD_COMBAD : (STD_FIRST_ERR-1), + STD_ARGBAD : (STD_FIRST_ERR-2), + STD_NOTNOW : (STD_FIRST_ERR-3), + STD_NOSPACE : (STD_FIRST_ERR-4), + STD_DENIED : (STD_FIRST_ERR-5), + STD_NOMEM : (STD_FIRST_ERR-6), + STD_EXISTS : (STD_FIRST_ERR-7), + STD_NOTFOUND : (STD_FIRST_ERR-8), + STD_SYSERR : (STD_FIRST_ERR-9), + STD_INTR : (STD_FIRST_ERR-10), + STD_OVERFLOW : (STD_FIRST_ERR-11), + STD_WRITEPROT : (STD_FIRST_ERR-12), + STD_NOMEDIUM : (STD_FIRST_ERR-13), + STD_IOERR : (STD_FIRST_ERR-14), + STD_WRONGSRV : (STD_FIRST_ERR-15), + STD_OBJBAD : (STD_FIRST_ERR-16), + STD_UNKNOWN : (STD_FIRST_ERR-17), + DNS_UNAVAIL : (DNS_FIRST_ERR -1), + DNS_NOTEMPTY : (DNS_FIRST_ERR -2), + DNS_UNREACH : (DNS_FIRST_ERR -3), + DNS_CLASH : (DNS_FIRST_ERR -4), + RPC_FAILURE : -1, + BUF_OVERFLOW : -2, + print: function(stat) { + switch(stat) { + case Status.STD_OK : return 'STD_OK'; + case Status.STD_CAPBAD : return 'STD_CAPBAD'; + case Status.STD_COMBAD : return 'STD_COMBAD'; + case Status.STD_ARGBAD : return 'STD_ARGBAD'; + case Status.STD_NOTNOW : return 'STD_NOTNOW'; + case Status.STD_NOSPACE : return 'STD_NOSPACE'; + case Status.STD_DENIED : return 'STD_DENIED'; + case Status.STD_NOMEM : return 'STD_NOMEM'; + case Status.STD_EXISTS : return 'STD_EXISTS'; + case Status.STD_NOTFOUND : return 'STD_NOTFOUND'; + case Status.STD_SYSERR : return 'STD_SYSERR'; + case Status.STD_INTR : return 'STD_INTR'; + case Status.STD_OVERFLOW : return 'STD_OVERFLOW'; + case Status.STD_WRITEPROT : return 'STD_WRITEPROT'; + case Status.STD_NOMEDIUM : return 'STD_NOMEDIUM'; + case Status.STD_IOERR : return 'STD_IOERR'; + case Status.STD_WRONGSRV : return 'STD_WRONGSRV'; + case Status.STD_OBJBAD : return 'STD_OBJBAD'; + case Status.STD_UNKNOWN : return 'STD_UNKNOWN'; + case Status.DNS_UNAVAIL : return 'DNS_UNAVAIL'; + case Status.DNS_NOTEMPTY : return 'DNS_NOTEMPTY'; + case Status.DNS_UNREACH : return 'DNS_UNREACH'; + case Status.DNS_CLASH : return 'DNS_CLASH'; + case Status.RPC_FAILURE : return 'RPC_FAILURE'; + case Status.BUF_OVERFLOW : return 'BUF_OVERFLOW'; + default : return '"'+stat+'"'; + } + } +}; + +/** RPC Command + * + * @enum {number} + */ + +var Command = { + /* + ** Standard Commands + */ + STD_MONITOR : STD_FIRST_COM, + STD_AGE : (STD_FIRST_COM+1), + STD_COPY : (STD_FIRST_COM + 2), + STD_DESTROY : (STD_FIRST_COM + 3), + STD_INFO : (STD_FIRST_COM + 4), + STD_RESTRICT : (STD_FIRST_COM + 5), + STD_STATUS : (STD_FIRST_COM + 6), + STD_TOUCH : (STD_FIRST_COM + 7), + STD_GETPARAMS : (STD_FIRST_COM + 8), + STD_SETPARAMS : (STD_FIRST_COM + 9), + STD_NTOUCH : (STD_FIRST_COM + 10), + STD_EXIT : (STD_FIRST_COM + 11), + STD_RIGHTS : (STD_FIRST_COM + 12), + STD_EXEC : (STD_FIRST_COM + 13), + STD_LOCATION : (STD_FIRST_COM + 20), + STD_LABEL : (STD_FIRST_COM + 21), + + /* + ** AFC Commands + */ + AFS_CREATE : (AFS_FIRST_COM + 1), + AFS_DELETE : (AFS_FIRST_COM + 2), + AFS_FSCK : (AFS_FIRST_COM + 3), + AFS_INSERT : (AFS_FIRST_COM + 4), + AFS_MODIFY : (AFS_FIRST_COM + 5), + AFS_READ : (AFS_FIRST_COM + 6), + AFS_SIZE : (AFS_FIRST_COM + 7), + AFS_DISK_COMPACT : (AFS_FIRST_COM + 8), + AFS_SYNC : (AFS_FIRST_COM + 9), + AFS_DESTROY : (AFS_FIRST_COM + 10), + + /* + ** DNS Commands + */ + + DNS_CREATE : (DNS_FIRST_COM), + DNS_DISCARD : (DNS_FIRST_COM + 1), + DNS_LIST : (DNS_FIRST_COM + 2), + DNS_APPEND : (DNS_FIRST_COM + 3), + DNS_CHMOD : (DNS_FIRST_COM + 4), + DNS_DELETE : (DNS_FIRST_COM + 5), + DNS_LOOKUP : (DNS_FIRST_COM + 6), + DNS_SETLOOKUP : (DNS_FIRST_COM + 7), + DNS_INSTALL : (DNS_FIRST_COM + 8), + DNS_REPLACE : (DNS_FIRST_COM + 10), + DNS_GETMASKS : (DNS_FIRST_COM + 11), + DNS_GETSEQNR : (DNS_FIRST_COM + 12), + DNS_RENAME : (DNS_FIRST_COM + 13), + DNS_GETROOT : (DNS_FIRST_COM + 14), + DNS_GETDEFAFS : (DNS_FIRST_COM + 15), + + PS_STUN : (PS_FIRST_COM), // Kill a process/ create a snapshot + PS_MIGRATE : (PS_FIRST_COM+1), // Execute a process from a snapshot after migration (->next+) + PS_EXEC : (PS_FIRST_COM+2), // Execute a process from a snapshot (->next) + PS_WRITE : (PS_FIRST_COM+4), // Store a process class template + PS_READ : (PS_FIRST_COM+5), // Get a process class template + PS_CREATE : (PS_FIRST_COM+6), // Create a process from a template and execute + PS_FORK : (PS_FIRST_COM+7), // Fork a process from a running process + PS_SIGNAL : (PS_FIRST_COM+8), // Send a signal to a process + + BR_CONNECT : (BR_FIRST_COM), + BR_DISCONN : (BR_FIRST_COM+1), + + print: function(cmd) { + switch(cmd) { + case Command.STD_MONITOR : return 'STD_MONITOR'; + case Command.STD_AGE : return 'STD_AGE'; + case Command.STD_COPY : return 'STD_COPY'; + case Command.STD_DESTROY : return 'STD_DESTROY'; + case Command.STD_INFO : return 'STD_INFO'; + case Command.STD_RESTRICT : return 'STD_RESTRICT'; + case Command.STD_STATUS : return 'STD_STATUS'; + case Command.STD_TOUCH : return 'STD_TOUCH'; + case Command.STD_GETPARAMS : return 'STD_GETPARAMS'; + case Command.STD_SETPARAMS : return 'STD_SETPARAMS'; + case Command.STD_NTOUCH : return 'STD_NTOUCH'; + case Command.STD_EXIT : return 'STD_EXIT'; + case Command.STD_RIGHTS : return 'STD_RIGHTS'; + case Command.STD_EXEC : return 'STD_EXEC'; + case Command.STD_LOCATION : return 'STD_LOCATION'; + case Command.STD_LABEL : return 'STD_LABEL'; + case Command.AFS_CREATE : return 'AFS_CREATE'; + case Command.AFS_DELETE : return 'AFS_DELETE'; + case Command.AFS_FSCK : return 'AFS_FSCK'; + case Command.AFS_INSERT : return 'AFS_INSERT'; + case Command.AFS_MODIFY : return 'AFS_MODIFY'; + case Command.AFS_READ : return 'AFS_READ'; + case Command.AFS_SIZE : return 'AFS_SIZE'; + case Command.AFS_DISK_COMPACT : return 'AFS_DISK_COMPACT'; + case Command.AFS_SYNC : return 'AFS_SYNC'; + case Command.AFS_DESTROY : return 'AFS_DESTROY'; + case Command.DNS_CREATE : return 'DNS_CREATE'; + case Command.DNS_DISCARD : return 'DNS_DISCARD'; + case Command.DNS_LIST : return 'DNS_LIST'; + case Command.DNS_APPEND : return 'DNS_APPEND'; + case Command.DNS_CHMOD : return 'DNS_CHMOD'; + case Command.DNS_DELETE : return 'DNS_DELETE'; + case Command.DNS_LOOKUP : return 'DNS_LOOKUP'; + case Command.DNS_SETLOOKUP : return 'DNS_SETLOOKUP'; + case Command.DNS_INSTALL : return 'DNS_INSTALL'; + case Command.DNS_REPLACE : return 'DNS_REPLACE'; + case Command.DNS_GETMASKS : return 'DNS_GETMASKS'; + case Command.DNS_GETSEQNR : return 'DNS_GETSEQNR'; + case Command.DNS_RENAME : return 'DNS_RENAME'; + case Command.DNS_GETROOT : return 'DNS_GETRROT'; + case Command.DNS_GETDEFAFS : return 'DNS_GETDEFAFS'; + case Command.PS_STUN : return 'PS_STUN'; + case Command.PS_EXEC : return 'PS_EXEC'; + case Command.PS_MIGRATE : return 'PS_MIGRATE'; + case Command.PS_READ : return 'PS_READ'; + case Command.PS_WRITE : return 'PS_WRITE'; + case Command.PS_CREATE : return 'PS_CREATE'; + case Command.PS_FORK : return 'PS_FORK'; + case Command.PS_SIGNAL : return 'PS_SIGNAL'; + case Command.BR_CONNECT : return 'BR_CONNECT'; + case Command.BR_DISCONN : return 'BR_DISCONN'; + default: return '"'+cmd+'"'; + } + + + } +}; + +var PORT_SIZE = 6; +var PRIV_SIZE = 4+PORT_SIZE; +var CAP_SIZE = 16; + +/** Object Rights + * + * @enum {number} + */ +var Rights = { + AFS_RGT_READ : 0x1, + AFS_RGT_CREATE : 0x2, + AFS_RGT_MODIFY : 0x4, + AFS_RGT_DESTROY : 0x8, + AFS_RGT_ADMIN : 0x80, + + DNS_COLMASK : ((1 << DNS_MAXCOLUMNS) - 1), // Rights to access specific columns of a directory row, one bit, one column. + DNS_RGT_COLALL : ((1 << DNS_MAXCOLUMNS) - 1), + DNS_RGT_COL1 : 0x01, + DNS_RGT_OWNER : 0x01, + DNS_RGT_COL2 : 0x02, + DNS_RGT_GROUP : 0x02, + DNS_RGT_COL3 : 0x04, + DNS_RGT_OTHERS : 0x04, + DNS_RGT_COL4 : 0x08, + DNS_RGT_READ : 0x10, + DNS_RGT_CREATE : 0x20, + DNS_RGT_MODIFY : 0x40, + DNS_RGT_DELETE : 0x80, + + HOST_INFO : 0x01, + HOST_READ : 0x02, + HOST_WRITE : 0x04, + HOST_EXEC : 0x08, + + PSR_READ : 0x01, + PSR_WRITE : 0x02, + PSR_CREATE : 0x04, + PSR_DELETE : 0x08, + PSR_EXEC : 0x10, + PSR_KILL : 0x20, + PSR_ALL : 0xff, + + NEG_SCHED : 0x08, + NEG_CPU : 0x10, + NEG_RES : 0x20, + NEG_LEVEL : 0x40, + + PRV_ALL_RIGHTS : 0xff + +}; + + + +var DEF_RPC_MAX_HOP = 4; + +var priv2pub_cache = []; + +/** + * + * @param {number []} [port_vals] + * @returns {string} + */ +var port = function (port_vals) { + if (port_vals==undefined) port_vals=[0,0,0,0,0,0]; + var port=''; + for(var i = 0; i< PORT_SIZE;i++) { + port=port+Perv.char_of_int(port_vals[i]); + } + return port; + +}; +/** + * + * @param {number} [obj] + * @param {number} [rights] + * @param {port} [rand] + * @constructor + */ +var privat = function (obj,rights,rand) { + if (obj==undefined) { + // Create empty private field + this.prv_obj=0; + this.prv_rights=0; + this.prv_rand=port(); + } else { + this.prv_obj = obj; // Integer + this.prv_rights = rights; // Integer + this.prv_rand = rand; // Port=string + } +}; + +/** + * + * @param {port} [cap_port] + * @param {privat} [cap_priv] + * @constructor + */ +var capability = function(cap_port, cap_priv) { + if (cap_port==undefined) { + // Create empty capability + this.cap_port = port(); + this.cap_priv = new privat(); + } else { + this.cap_port = cap_port; // Port=string + if (cap_priv==undefined) + this.cap_priv = new privat(); + else + this.cap_priv = cap_priv; // Private + } +}; + +/* + ** RPC communication is XML based using the HTTP interface. + ** RPC communication is synchronous, hence a callback + ** function is used to handle the reply (acknowledge). + */ +/** + * + * @param {port} [h_port] + * @param {privat} [h_priv] + * @param {Command} [h_command] + * @param {(Status.STD_OK|*)} [h_status] + * @constructor + */ +var header = function(h_port,h_priv,h_command,h_status) { + if (h_port==undefined) { + // Create empty header + this.h_port = port(); + this.h_priv = new privat(); + this.h_command = undefined; + this.h_status = undefined; + } else { + this.h_port = h_port; + this.h_priv = h_priv; + this.h_command = h_command; + this.h_status = h_status; + } +}; + +/** + * + * @param {number} [obj] + * @param {number} [rights] + * @param {port} [rand] + * @returns {privat} + */ +function Private(obj,rights,rand) { + var _obj = new privat(obj,rights,rand); + Object.preventExtensions(_obj); + return _obj; +} +/** + * + * @param {port} [cap_port] + * @param {privat} [cap_priv] + * @returns {capability} + */ +function Capability (cap_port, cap_priv) { + var obj = new capability(cap_port, cap_priv); + Object.preventExtensions(obj); + return obj; +} +/** + * + * @param {port} [h_port] + * @param {privat} [h_priv] + * @param {Command} [h_command] + * @param {(Status.STD_OK|*)} [h_status] + * @returns {header} + */ + +function Header(h_port,h_priv,h_command,h_status) { + var obj = new header(h_port,h_priv,h_command,h_status); + Object.preventExtensions(obj); + return obj; +} + +/* +** Hash table of all locally created unique ports. + */ +var uniqports=[]; + + +/** + * + */ +var Net = { + // Direction:Direction, + PORT_SIZE:PORT_SIZE, + PRIV_SIZE:PRIV_SIZE, + + AFS_REQBUFSZ:AFS_REQBUFSZ, + CAP_SIZE:CAP_SIZE, + DNS_MAXCOLUMNS:DNS_MAXCOLUMNS, + TIMEOUT:5000, + DEF_RPC_MAX_HOP:DEF_RPC_MAX_HOP, + + Status:Status, + Command:Command, + Rights:Rights, + + Private:Private, + Capability: Capability, + Header: Header, + Port: port, + + /** + * @type {port} + */ + nilport: port(), + nilpriv: Private(0,0,this.nilport), + nilcap: Capability(this.nilport,this.nilpriv), + + /* + ** Utils to get and set single bytes of a port + */ + get_portbyte: function(port,i) { + return Perv.int_of_char(String.get(port,i)) + }, + set_portbyte: function(port,i,byte) { + return String.set(port, i, (Perv.char_of_int(byte))); + }, + /* + * Return a unique key of a capability that can be used for hash tables + */ + key: function (cap) { + return cap.cap_port+ + cap.cap_priv.prv_obj+ + cap.cap_priv.prv_rights+ + cap.cap_priv.prv_rand; + }, + + /* + ** Encryption function + */ + one_way: function (port) { + var key = Array.create(64,0); + var block = Array.create(48,0); + var pubport = String.make (PORT_SIZE,'\0'); + var i, j, k; + + /* + ** We actually need 64 bit key. + ** Throw some zeroes in at bits 6 and 7 mod 8 + ** The bits at 7 mod 8 etc are not used by the algorithm + */ + j=0; + for (i = 0; i< 64; i++) { + if ((i & 7) > 5) + key[i] = 0; + else { + if ((this.get_portbyte(port, (j >> 3)) & (1 << (j & 7))) != 0) + key[i] = 1; + else + key[i] = 0; + j++; + } + } + + Des48.des_OWsetkey(key); + /* + ** Now go encrypt constant 0 + */ + block=Des48.des_OWcrypt48(block); + + + /* + ** and put the bits in the destination port + */ + var pb = 0; + + for (i = 0; i < PORT_SIZE;i++) { + var pbyte = 0; + for (j = 0; j < 8; j++) { + pbyte = pbyte | (block[pb] << j); + pb++; + } + pubport=this.set_portbyte(pubport, i, pbyte); + } + + return pubport; + }, + /* + ** Check whether the required rights [R1;R2;..] are + ** present in the rights field rg. Return a boolean value. + */ + rights_req : function(rights,required) { + var all=true; + Array.iter(required,function(rq) { + if (rq & rights == 0) all = false; + }); + return all; + }, + port_cmp: function(port1,port2) { + var i; + var eq=true; + for(i=0;i 0) str = str + ':'; + str = str + pad(num.toString(16).toUpperCase(), 2); + } + } else str='undefined'; + return str; + }, + port_of_str: function (str,compact) { + var tokens=str.split(':'),i,port=''; + for (i=0;i 0) str = str + ':'; + str = str + pad(num.toString(16).toUpperCase(), 2); + } + } else str='undefined'; + return str; + }, + /** + * + * @param priv + * @returns {string} + */ + private: function(priv) { + var str=''; + if (priv==undefined) return 'undefined'; + str=priv.prv_obj; + str=str+'('+String.format_hex(priv.prv_rights,2).toUpperCase()+')['; + str=str+this.port(priv.prv_rand)+']'; + return str; + }, + status: Status.print + } +}; + +module.exports = Net;