From 408d2237f4bb47fe6a265888425f1d9952d03f13 Mon Sep 17 00:00:00 2001 From: Ahmed Zamil Date: Sat, 22 Jun 2024 16:12:35 +0300 Subject: [PATCH] IntTYpes --- demo/chat/chat.js | 6 +- src/Data/DataDeserializer.js | 17 +- src/Data/ExtendedTypes.js | 303 +++++++++++++++++++++++-- src/Net/IIP/DistributedConnection.js | 88 +++---- src/Net/Packets/IIPAuthPacket.js | 17 +- src/Net/Packets/IIPAuthPacketHeader.js | 40 ++-- src/Net/SendList.js | 2 +- src/Security/Authority/Session.js | 7 +- 8 files changed, 390 insertions(+), 90 deletions(-) diff --git a/demo/chat/chat.js b/demo/chat/chat.js index f76a074..dcf647c 100644 --- a/demo/chat/chat.js +++ b/demo/chat/chat.js @@ -26,7 +26,7 @@ const wss = new WebSocket.Server({port: 8001}); class MyMembership extends IMembership { userExists(username, domain) { - return new AsyncReply(true); + return new AsyncReply(username); } getPassword(username, domain) { return new AsyncReply(DC.stringToBytes("1234")); @@ -83,9 +83,9 @@ wss.on('connection', function connection(ws) let con = server.add(); con.assign(new WSocket(ws)); con.on("ready", (x)=>{ - chat._emit("login", x.session.remoteAuthentication.username); + chat._emit("login", x.session.authorizedAccount); }).on("close", (x)=>{ - chat._emit("logout", x.session.remoteAuthentication.username); + chat._emit("logout", x.session.authorizedAccount); }); }); diff --git a/src/Data/DataDeserializer.js b/src/Data/DataDeserializer.js index d2ae9c8..2333b5a 100644 --- a/src/Data/DataDeserializer.js +++ b/src/Data/DataDeserializer.js @@ -13,11 +13,12 @@ import TypedMap from './TypedMap.js'; import PropertyValueArray from './PropertyValueArray.js'; import PropertyValue from './PropertyValue.js'; import Record from './Record.js'; -import { UInt64, Int64 } from '../Data/ExtendedTypes.js'; import AsyncException from '../Core/AsyncException.js'; import ExceptionCode from '../Core/ExceptionCode.js'; import ErrorType from '../Core/ErrorType.js'; +import {Int8, UInt8, Int16, UInt16, Int32, UInt32, Float32, Float64, UInt64, Int64} from './ExtendedTypes.js'; + export class PropertyValueParserResults { //final int size; ///final AsyncReply reply; @@ -50,13 +51,13 @@ export default class DataDeserializer { static byteParser( data, offset, length, connection, requestSequence) { - return new AsyncReply(data[offset]); + return new AsyncReply(new UInt8(data[offset])); } static sByteParser( data, offset, length, connection, requestSequence) { return new AsyncReply( - data[offset] > 127 ? data[offset] - 256 : data[offset]); + new Int8(data[offset] > 127 ?data[offset] - 256 : data[offset])); } static char16Parser( @@ -71,27 +72,27 @@ export default class DataDeserializer { static int16Parser( data, offset, length, connection, requestSequence) { - return new AsyncReply(data.getInt16(offset)); + return new AsyncReply(new Int16(data.getInt16(offset))); } static uInt16Parser( data, offset, length, connection, requestSequence) { - return new AsyncReply(data.getUint16(offset)); + return new AsyncReply(new UInt16(data.getUint16(offset))); } static int32Parser( data, offset, length, connection, requestSequence) { - return new AsyncReply(data.getInt32(offset)); + return new AsyncReply(new Int32(data.getInt32(offset))); } static uInt32Parser( data, offset, length, connection, requestSequence) { - return new AsyncReply(data.getUint32(offset)); + return new AsyncReply(new UInt32(data.getUint32(offset))); } static float32Parser( data, offset, length, connection, requestSequence) { - return new AsyncReply(data.getFloat32(offset)); + return new AsyncReply(new Float32(data.getFloat32(offset))); } static float64Parser( diff --git a/src/Data/ExtendedTypes.js b/src/Data/ExtendedTypes.js index 7a7ee25..dcec535 100644 --- a/src/Data/ExtendedTypes.js +++ b/src/Data/ExtendedTypes.js @@ -2,27 +2,298 @@ class Num extends Number { toString() { return super.toString()} + static #cache = new WeakMap(); + constructor(value) { super(value); } + } -export class Int128 extends Num {} -export class Int64 extends Num { } -export class Int32 extends Num { } -export class Int16 extends Num { } -export class Int8 extends Num { } +export class Int128 extends Num { -export class UInt128 extends Num {} -export class UInt64 extends Num { } -export class UInt32 extends Num { } -export class UInt16 extends Num { } -export class UInt8 extends Num { } - -export class Float32 extends Num{} -export class Float64 extends Num{} + static #cache = new Map(); -export class Float128 extends Num{} + constructor(value) { -export class Char16 extends String {} -export class Char8 extends String {} \ No newline at end of file + if (Int128.#cache.has(value)) + { + let v = Int128.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Int128.#cache.set(value, new WeakRef (this)); + + } +} + + +export class Int64 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (Int64.#cache.has(value)) + { + let v = Int64.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Int64.#cache.set(value, new WeakRef (this)); + + } +} + +export class Int32 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (Int32.#cache.has(value)) + { + let v = Int32.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Int32.#cache.set(value, new WeakRef (this)); + + } +} + +export class Int16 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (Int16.#cache.has(value)) + { + let v = Int16.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Int16.#cache.set(value, new WeakRef (this)); + + } +} +export class Int8 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (Int8.#cache.has(value)) + { + let v = Int8.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Int8.#cache.set(value, new WeakRef (this)); + + } + +} + +export class UInt128 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (UInt128.#cache.has(value)) + { + let v = UInt128.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + UInt128.#cache.set(value, new WeakRef (this)); + + } +} +export class UInt64 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (UInt64.#cache.has(value)) + { + let v = UInt64.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + UInt64.#cache.set(value, new WeakRef (this)); + + } + +} +export class UInt32 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (UInt32.#cache.has(value)) + { + let v = UInt32.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + UInt32.#cache.set(value, new WeakRef (this)); + + } + +} +export class UInt16 extends Num { + static #cache = new Map(); + + constructor(value) { + + if (UInt16.#cache.has(value)) + { + let v = UInt16.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + UInt16.#cache.set(value, new WeakRef (this)); + + } + +} + +export class UInt8 extends Num { + + static #cache = new Map(); + + constructor(value) { + + if (UInt8.#cache.has(value)) + { + let v = UInt8.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + UInt8.#cache.set(value, new WeakRef (this)); + + } +} + +export class Float32 extends Num{ + static #cache = new Map(); + + constructor(value) { + + if (Float32.#cache.has(value)) + { + let v = Float32.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Float32.#cache.set(value, new WeakRef (this)); + + } +} +export class Float64 extends Num{ + static #cache = new Map(); + + constructor(value) { + + if (Float64.#cache.has(value)) + { + let v = Float64.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Float64.#cache.set(value, new WeakRef (this)); + + } + +} + +export class Float128 extends Num{ + static #cache = new Map(); + + constructor(value) { + + if (Float128.#cache.has(value)) + { + let v = Float128.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Float128.#cache.set(value, new WeakRef (this)); + + } + +} + +export class Char16 extends String { + static #cache = new Map(); + + constructor(value) { + + if (Char16.#cache.has(value)) + { + let v = Char16.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Char16.#cache.set(value, new WeakRef (this)); + + } +} +export class Char8 extends String { + static #cache = new Map(); + + constructor(value) { + + if (Char8.#cache.has(value)) + { + let v = Char8.#cache.get(value).deref(); + if (v != null) + return v; + } + + super(value); + + Char8.#cache.set(value, new WeakRef (this)); + + } +} \ No newline at end of file diff --git a/src/Net/IIP/DistributedConnection.js b/src/Net/IIP/DistributedConnection.js index b302c21..a32df96 100644 --- a/src/Net/IIP/DistributedConnection.js +++ b/src/Net/IIP/DistributedConnection.js @@ -42,11 +42,18 @@ import AsyncQueue from '../../Core/AsyncQueue.js'; import Warehouse from '../../Resource/Warehouse.js'; import IIPAuthPacket from "../Packets/IIPAuthPacket.js"; -import IIPPacket from "../Packets/IIPPacket.js"; -import IIPAuthPacketAction from "../Packets/IIPAuthPacketAction.js"; import IIPAuthPacketCommand from "../Packets/IIPAuthPacketCommand.js"; +import IIPAuthPacketHeader from '../../Net/Packets/IIPAuthPacketHeader.js'; +import IIPAuthPacketInitialize from '../../Net/Packets/IIPAuthPacketInitialize.js'; +import IIPAuthPacketAcknowledge from '../../Net/Packets/IIPAuthPacketAcknowledge.js'; +import IIPAuthPacketAction from '../../Net/Packets/IIPAuthPacketAction.js'; +import IIPAuthPacketEvent from '../../Net/Packets/IIPAuthPacketEvent.js'; + + + import AuthenticationMethod from "../../Security/Authority/AuthenticationMethod.js"; +import IIPPacket from "../Packets/IIPPacket.js"; import IIPPacketAction from "../Packets/IIPPacketAction.js"; import IIPPacketCommand from "../Packets/IIPPacketCommand.js"; import IIPPacketEvent from "../Packets/IIPPacketEvent.js"; @@ -85,8 +92,6 @@ import ConnectionStatus from './ConnectionStatus.js'; import { Prop, TemplateDescriber } from '../../Resource/Template/TemplateDescriber.js'; import TypedMap from '../../Data/TypedMap.js'; -import IIPAuthPacketHeader from '../../Net/Packets/IIPAuthPacketHeader.js'; - export default class DistributedConnection extends IStore { // fields @@ -147,7 +152,7 @@ export default class DistributedConnection extends IStore { return this.#status; } - #sendAll(data) { + _sendAll(data) { this.#socket.sendAll(data.buffer); } @@ -475,10 +480,10 @@ export default class DistributedConnection extends IStore { else { offset += rt; - if (session.authenticationType == AuthenticationType.Host) { + if (this.#session.authenticationType == AuthenticationType.Host) { this.#processHostAuth(msg); } - else if (session.authenticationType == AuthenticationType.Client) { + else if (this.#session.authenticationType == AuthenticationType.Client) { this.#processClientAuth(msg); } } @@ -525,12 +530,12 @@ export default class DistributedConnection extends IStore { else if (session.localMethod == AuthenticationMethod.Credentials || session.localMethod == AuthenticationMethod.Token) { - var remoteNonce = session.remoteHeaders[IIPAuthPacketHeader.Nonce]; - var localNonce = session.localHeaders[IIPAuthPacketHeader.Nonce]; + var remoteNonce = session.remoteHeaders.get(IIPAuthPacketHeader.Nonce); + var localNonce = session.localHeaders.get(IIPAuthPacketHeader.Nonce); // send our hash // local nonce + password or token + remote nonce - var challenge = SHA256.compute((new BinaryList() + var challenge = SHA256.compute((BL() .addDC(localNonce) .addDC(this.#localPasswordOrToken) .addDC(remoteNonce)) @@ -550,12 +555,12 @@ export default class DistributedConnection extends IStore { { if (authPacket.action == IIPAuthPacketAction.AuthenticateHash) { - var remoteNonce = session.remoteHeaders[IIPAuthPacketHeader.Nonce]; - var localNonce = session.localHeaders[IIPAuthPacketHeader.Nonce]; + var remoteNonce = session.remoteHeaders.get(IIPAuthPacketHeader.Nonce); + var localNonce = session.localHeaders.get(IIPAuthPacketHeader.Nonce); // check if the server knows my password - var challenge = SHA256.compute((new BinaryList() + var challenge = SHA256.compute((BL() .addDC(remoteNonce) .addDC(this.#localPasswordOrToken) .addDC(localNonce) @@ -601,7 +606,8 @@ export default class DistributedConnection extends IStore { else if (authPacket.event == IIPAuthPacketEvent.IndicationEstablished) { session.id = authPacket.sessionId; - + session.authorizedAccount = authPacket.accountId.getString(0, authPacket.accountId.length); + this.#ready = true; this.#status = ConnectionStatus.Connected; @@ -609,7 +615,7 @@ export default class DistributedConnection extends IStore { if (this.instance == null) { - Warehouse.put(this.hashCode.toString().replaceAll("/", "_"), this, null, this.#server).then((x) => + Warehouse.put(session.authorizedAccount.replaceAll("/", "_"), this, null, this.#server).then((x) => { this.#openReply?.trigger(true); @@ -692,10 +698,10 @@ export default class DistributedConnection extends IStore { this.authenticator(headers).then((response) => { - var hash = SHA256.compute((new BinaryList() - .addDC(session.localHeaders[IIPAuthPacketHeader.Nonce]) + var hash = SHA256.compute((BL() + .addDC(session.localHeaders.get(IIPAuthPacketHeader.Nonce)) .addDC(Codec.compose(response, this)) - .addDC(session.remoteHeaders[IIPAuthPacketHeader.Nonce]) + .addDC(session.remoteHeaders.get(IIPAuthPacketHeader.Nonce)) ).toDC()); this.#sendParams() @@ -750,10 +756,10 @@ export default class DistributedConnection extends IStore { try { - var username = session.remoteHeaders[IIPAuthPacketHeader.Username]; - var domain = session.remoteHeaders[IIPAuthPacketHeader.Domain]; + var username = session.remoteHeaders.get(IIPAuthPacketHeader.Username); + var domain = session.remoteHeaders.get(IIPAuthPacketHeader.Domain); - if (_server?.membership == null) + if (this.#server?.membership == null) { var errMsg = DC.stringToBytes("Membership not set."); @@ -820,8 +826,8 @@ export default class DistributedConnection extends IStore { // Check if user and token exists else { - let tokenIndex = session.remoteHeaders[IIPAuthPacketHeader.TokenIndex]; - let domain = session.remoteHeaders[IIPAuthPacketHeader.Domain]; + let tokenIndex = session.remoteHeaders.get(IIPAuthPacketHeader.TokenIndex); + let domain = session.remoteHeaders.get(IIPAuthPacketHeader.Domain); this.#server?.membership?.tokenExists(tokenIndex, domain).then((x) => @@ -920,13 +926,13 @@ export default class DistributedConnection extends IStore { { if (session.remoteMethod == AuthenticationMethod.Credentials) { - reply = this.#server.membership.getPassword(session.remoteHeaders[IIPAuthPacketHeader.Username], - session.remoteHeaders[IIPAuthPacketHeader.Domain]); + reply = this.#server.membership.getPassword(session.remoteHeaders.get(IIPAuthPacketHeader.Username), + session.remoteHeaders.get(IIPAuthPacketHeader.Domain)); } else if (session.remoteMethod == AuthenticationMethod.Token) { - reply = this.#server.membership.getToken(session.remoteHeaders[IIPAuthPacketHeader.TokenIndex], - session.remoteHeaders[IIPAuthPacketHeader.Domain]); + reply = this.#server.membership.getToken(session.remoteHeaders.get(IIPAuthPacketHeader.TokenIndex), + session.remoteHeaders.get(IIPAuthPacketHeader.Domain)); } else { @@ -938,11 +944,11 @@ export default class DistributedConnection extends IStore { { if (pw != null) { - let localNonce = session.localHeaders[IIPAuthPacketHeader.Nonce]; - let remoteNonce = session.remoteHeaders[IIPAuthPacketHeader.Nonce]; + let localNonce = session.localHeaders.get(IIPAuthPacketHeader.Nonce); + let remoteNonce = session.remoteHeaders.get(IIPAuthPacketHeader.Nonce); - let hash = SHA256.compute((new BinaryList() + let hash = SHA256.compute((BL() .addDC(remoteNonce) .addDC(pw) .addDC(localNonce) @@ -951,7 +957,7 @@ export default class DistributedConnection extends IStore { if (hash.sequenceEqual(remoteHash)) { // send our hash - let localHash = SHA256.compute((new BinaryList() + let localHash = SHA256.compute((BL() .addDC(localNonce) .addDC(pw) .addDC(remoteNonce) @@ -1069,10 +1075,14 @@ export default class DistributedConnection extends IStore { session.id = n; + let accountId = DC.stringToBytes(session.authorizedAccount); + this.#sendParams() .addUint8(IIPAuthPacketEvent.IndicationEstablished) .addUint8(n.length) - .addDC(n) + .addUint8Array(n) + .addUint8(accountId.length) + .addUint8Array(accountId) .done(); if (this.instance == null) @@ -1391,16 +1401,16 @@ export default class DistributedConnection extends IStore { this.#session.localMethod = method; this.#session.remoteMethod = AuthenticationMethod.None; - this.#session.localHeaders[IIPAuthPacketHeader.Domain] = domain; - this.#session.localHeaders[IIPAuthPacketHeader.Nonce] = this.#generateCode(32); + this.#session.localHeaders.set(IIPAuthPacketHeader.Domain, domain); + this.#session.localHeaders.set(IIPAuthPacketHeader.Nonce, this.#generateCode(32)); if (method == AuthenticationMethod.Credentials) { - this.#session.localHeaders[IIPAuthPacketHeader.Username] = username; + this.#session.localHeaders.set(IIPAuthPacketHeader.Username, username); } else if (method == AuthenticationMethod.Token) { - this.#session.localHeaders[IIPAuthPacketHeader.TokenIndex] = tokenIndex; + this.#session.localHeaders.set(IIPAuthPacketHeader.TokenIndex, tokenIndex); } else if (method == AuthenticationMethod.Certificate) { @@ -1462,7 +1472,7 @@ export default class DistributedConnection extends IStore { && this.#session.remoteMethod == AuthenticationMethod.None) { // change to Map for compatibility - let headers = Codec.compose(session.localHeaders, this); + let headers = Codec.compose(this.#session.localHeaders, this); // declare (Credentials -> No Auth, No Enctypt) this.#sendParams() @@ -1508,7 +1518,7 @@ export default class DistributedConnection extends IStore { // @TODO: add referer // this.#session.LocalHeaders[IIPAuthPacketHeader.IPv4] = socket.remoteEndPoint.Address.Address; - if (socket.State == SocketState.Established && + if (socket.state == SocketState.Established && this.#session.authenticationType == AuthenticationType.Client) { this.#declare(); @@ -2172,7 +2182,7 @@ export default class DistributedConnection extends IStore { { // get all templates related to this resource - var msg = new BinaryList(); + var msg = BL(); var templates = []; for (var i = 0; i < list.length; i++) diff --git a/src/Net/Packets/IIPAuthPacket.js b/src/Net/Packets/IIPAuthPacket.js index 8a347d8..1c5fc0e 100644 --- a/src/Net/Packets/IIPAuthPacket.js +++ b/src/Net/Packets/IIPAuthPacket.js @@ -30,6 +30,7 @@ import IIPAuthPacketCommand from "./IIPAuthPacketCommand.js"; import IIPAuthPacketAction from "./IIPAuthPacketAction.js"; import AuthenticationMethod from "../../Security/Authority/AuthenticationMethod.js"; +import TransmissionType from '../../Data/TransmissionType.js'; export default class IIPAuthPacket { @@ -52,6 +53,7 @@ export default class IIPAuthPacket challenge = null; asymetricEncryptionKey = null; sessionId = null; + accountId = null; dataType = null; @@ -300,7 +302,7 @@ export default class IIPAuthPacket } else if (this.event == IIPAuthPacketEvent.IndicationEstablished) { - if (this.#notEnough(offset, ends, 1)) + if (this.#notEnough(offset, ends, 2)) return -this.#dataLengthNeeded; let sessionLength = data[offset++]; @@ -311,6 +313,19 @@ export default class IIPAuthPacket this.sessionId = data.clip(offset, sessionLength); offset += sessionLength; + + if (this.#notEnough(offset, ends, 1)) + return -this.#dataLengthNeeded; + + let accountLength = data[offset++]; + + if (this.#notEnough(offset, ends, accountLength)) + return -this.#dataLengthNeeded; + + this.accountId = data.clip(offset, accountLength); + + offset += accountLength; + } else if (this.event == IIPAuthPacketEvent.IAuthPlain || this.event == IIPAuthPacketEvent.IAuthHashed || diff --git a/src/Net/Packets/IIPAuthPacketHeader.js b/src/Net/Packets/IIPAuthPacketHeader.js index 2ecf648..835a0f0 100644 --- a/src/Net/Packets/IIPAuthPacketHeader.js +++ b/src/Net/Packets/IIPAuthPacketHeader.js @@ -1,22 +1,24 @@ +import { UInt8 } from "../../Data/ExtendedTypes.js"; + // IIPAuthPacketHeader export default { - Version: 0, - Domain: 1, - SupportedAuthentications: 2, - SupportedHashAlgorithms: 3, - SupportedCiphers: 4, - SupportedCompression: 5, - SupportedPersonalAuth: 6, - Nonce: 7, - Username: 8, - TokenIndex: 9, - CertificateId: 10, - CachedCertificates: 11, - CipherType: 12, - CipherKey: 13, - SoftwareIdentity: 14, - Referrer: 15, - Time: 16, - Certificate: 17, - IPv4: 18 + Version: new UInt8(0), + Domain: new UInt8(1), + SupportedAuthentications: new UInt8(2), + SupportedHashAlgorithms: new UInt8(3), + SupportedCiphers: new UInt8(4), + SupportedCompression: new UInt8(5), + SupportedPersonalAuth: new UInt8(6), + Nonce: new UInt8(7), + Username: new UInt8(8), + TokenIndex: new UInt8(9), + CertificateId: new UInt8(10), + CachedCertificates: new UInt8(11), + CipherType: new UInt8(12), + CipherKey: new UInt8(13), + SoftwareIdentity: new UInt8(14), + Referrer: new UInt8(15), + Time: new UInt8(16), + Certificate: new UInt8(17), + IPv4: new UInt8(18) } \ No newline at end of file diff --git a/src/Net/SendList.js b/src/Net/SendList.js index d53cb1a..67ff7c4 100644 --- a/src/Net/SendList.js +++ b/src/Net/SendList.js @@ -39,7 +39,7 @@ export default class SendList extends BinaryList done() { - this.connection.sendAll(this.toArray()); + this.connection._sendAll(this.toArray()); return this.reply; } } \ No newline at end of file diff --git a/src/Security/Authority/Session.js b/src/Security/Authority/Session.js index 2ec81f0..12166c3 100644 --- a/src/Security/Authority/Session.js +++ b/src/Security/Authority/Session.js @@ -29,7 +29,8 @@ import AuthenticationType from "./AuthenticationType.js"; import AuthenticationMethod from "./AuthenticationMethod.js"; import KeyList from "../../Data/KeyList.js"; - +import { UInt8 } from "../../Data/ExtendedTypes.js"; +import TypedMap from "../../Data/TypedMap.js"; export default class Session { @@ -39,8 +40,8 @@ export default class Session variables = new KeyList(); - localHeaders = new Map(); - remoteHeaders = new Map(); + localHeaders = new (TypedMap.of(UInt8, Object))(); + remoteHeaders = new (TypedMap.of(UInt8, Object))(); localMethod = AuthenticationMethod.None; remoteMethod = AuthenticationMethod.None;