holy shit we're actually talking
wew
This commit is contained in:
parent
769fbc315f
commit
73ec4544f1
19 changed files with 119 additions and 39 deletions
|
@ -116,8 +116,10 @@
|
||||||
<h2>An error occurred.</h2>
|
<h2>An error occurred.</h2>
|
||||||
|
|
||||||
<p><i>Details: <span id="errorText"></span></i></p>
|
<p><i>Details: <span id="errorText"></span></i></p>
|
||||||
|
<p>
|
||||||
<p>Please report this error to <a href="mailto:aleco@aroltd.com">aleco@aroltd.com</a>.
|
Please report this error to <a href="mailto:aleco@aroltd.com">aleco@aroltd.com</a>.
|
||||||
|
</p>
|
||||||
|
<p><a href="index.html">Click here to try again.</a></p>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -13,6 +13,7 @@ class Connection {
|
||||||
|
|
||||||
// FLAG replace hard coded url with one loaded from a config file
|
// FLAG replace hard coded url with one loaded from a config file
|
||||||
Connection.sock = new WebSocket("ws://localhost:6770");
|
Connection.sock = new WebSocket("ws://localhost:6770");
|
||||||
|
Connection.sock.binaryType = "arraybuffer";
|
||||||
|
|
||||||
Connection.onOpenFunc = onOpen;
|
Connection.onOpenFunc = onOpen;
|
||||||
Connection.sock.onopen = Connection.onOpen;
|
Connection.sock.onopen = Connection.onOpen;
|
||||||
|
@ -28,8 +29,10 @@ class Connection {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static onMessage(event: any): void {
|
private static onMessage(event: any): void {
|
||||||
var msg = Packet.fromBytes(event.data);
|
var raw = new Uint8Array(event.data);
|
||||||
|
var msg = Packet.fromBytes(raw);
|
||||||
console.log(msg);
|
console.log(msg);
|
||||||
|
console.log(msg[1].toString());
|
||||||
|
|
||||||
switch(msg.id) {
|
switch(msg.id) {
|
||||||
case kPacketId.KeyExchange:
|
case kPacketId.KeyExchange:
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
/// <reference path="FileCache.ts" />
|
|
||||||
/// <reference path="Utilities.ts" />
|
|
||||||
|
|
||||||
class Entrypoint {
|
class Entrypoint {
|
||||||
private static initStatus = {
|
private static initStatus = {
|
||||||
fileCache: false
|
fileCache: false
|
||||||
|
@ -16,6 +13,8 @@ class Entrypoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static start(): void {
|
public static start(): void {
|
||||||
|
Connection.open();
|
||||||
|
|
||||||
FileCache.initCache(
|
FileCache.initCache(
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
() => {
|
() => {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
/// <reference path="def/UTF8.d.ts" />
|
|
||||||
|
|
||||||
// ** STRING EXTENSIONS ** \\
|
// ** STRING EXTENSIONS ** \\
|
||||||
|
|
||||||
interface String {
|
interface String {
|
||||||
|
@ -162,6 +160,8 @@ interface Uint8Array {
|
||||||
|
|
||||||
unpackFloat(offset?: number): number;
|
unpackFloat(offset?: number): number;
|
||||||
unpackDouble(offset?: number): number;
|
unpackDouble(offset?: number): number;
|
||||||
|
|
||||||
|
toHexString(): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8Array.prototype.unpackInt16 = function(offset: number = 0): number {
|
Uint8Array.prototype.unpackInt16 = function(offset: number = 0): number {
|
||||||
|
@ -202,4 +202,34 @@ Uint8Array.prototype.toString = function(): string {
|
||||||
raw += String.fromCharCode.apply(null, this.subarray(chunkSize*i, chunkSize*i + chunkSize));
|
raw += String.fromCharCode.apply(null, this.subarray(chunkSize*i, chunkSize*i + chunkSize));
|
||||||
}
|
}
|
||||||
return utf8.decode(raw);
|
return utf8.decode(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8Array.prototype.toHexString = function(): string {
|
||||||
|
var ret = "";
|
||||||
|
for(var i = 0; i < this.byteLength; ++i) {
|
||||||
|
var byte = this[i].toString(16);
|
||||||
|
if(byte.length < 2)
|
||||||
|
byte = "0"+ byte;
|
||||||
|
|
||||||
|
ret += byte +" ";
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ** BIGINT EXTENSIONS ** \\
|
||||||
|
|
||||||
|
interface bigInt {
|
||||||
|
toByteArray(): Uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
bigInt.prototype.toByteArray = function(): Uint8Array {
|
||||||
|
var hexString: string = this.toString(16);
|
||||||
|
var byteCount = Math.ceil(hexString.length / 2);
|
||||||
|
var byteArray = new Uint8Array(byteCount);
|
||||||
|
|
||||||
|
for(var i = 0; i < byteCount; ++i) {
|
||||||
|
byteArray[i] = parseInt(hexString.substr(Math.max(0, hexString.length - 2*(i+1)), hexString.length - 2*i), 16);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -8,8 +8,10 @@ class FileCache {
|
||||||
var db: IDBDatabase = event.target.result;
|
var db: IDBDatabase = event.target.result;
|
||||||
|
|
||||||
var stores = db.objectStoreNames;
|
var stores = db.objectStoreNames;
|
||||||
|
/*
|
||||||
for(var i in stores)
|
for(var i in stores)
|
||||||
db.deleteObjectStore(stores[i]);
|
db.deleteObjectStore(i);
|
||||||
|
*/
|
||||||
|
|
||||||
db.createObjectStore("files", {keyPath: "name", autoIncrement: false});
|
db.createObjectStore("files", {keyPath: "name", autoIncrement: false});
|
||||||
db.createObjectStore("metadata", {keyPath: "name", autoIncrement: false});
|
db.createObjectStore("metadata", {keyPath: "name", autoIncrement: false});
|
||||||
|
|
|
@ -23,18 +23,26 @@ class Packet {
|
||||||
public getRegionString(region: number): string {
|
public getRegionString(region: number): string {
|
||||||
return this.getRegion(region).toString();
|
return this.getRegion(region).toString();
|
||||||
}
|
}
|
||||||
public addRegion(region: object): void {
|
public addRegion(region: object): Packet {
|
||||||
if(typeof region == "string")
|
if(typeof region == "string")
|
||||||
this._regions.push((<string>region).toByteArray());
|
this._regions.push((<string>region).toByteArray());
|
||||||
else if(region instanceof Uint8Array)
|
else if(region instanceof Uint8Array)
|
||||||
this._regions.push(region);
|
this._regions.push(region);
|
||||||
|
|
||||||
|
this[this.regionCount-1] = this._regions[this.regionCount-1];
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Packet(id: kPacketId, regions: any[]) {
|
private constructor() {}
|
||||||
this._id = id;
|
|
||||||
|
public static create(id: kPacketId, regions: any[]): Packet {
|
||||||
|
var packet = new Packet;
|
||||||
|
packet._id = id;
|
||||||
regions.forEach(region => {
|
regions.forEach(region => {
|
||||||
this.addRegion(region);
|
packet.addRegion(region);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static fromBytes(bytes: Uint8Array): Packet {
|
public static fromBytes(bytes: Uint8Array): Packet {
|
||||||
|
@ -58,7 +66,7 @@ class Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i = 0; i < regionCount; ++i) {
|
for(var i = 0; i < regionCount; ++i) {
|
||||||
packet.regions.push(bytes.subarray(ptr, ptr + regionLengths[i]));
|
packet.addRegion(bytes.subarray(ptr, ptr + regionLengths[i]));
|
||||||
ptr += regionLengths[i];
|
ptr += regionLengths[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace Server.DAL
|
namespace CircleScape.DAL
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Data.Entity;
|
using System.Data.Entity;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace Server.DAL
|
namespace CircleScape.DAL
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// </auto-generated>
|
// </auto-generated>
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace Server.DAL
|
namespace CircleScape.DAL
|
||||||
{
|
{
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Square;
|
using Square;
|
||||||
|
|
||||||
namespace Server.Encryption {
|
namespace CircleScape.Encryption {
|
||||||
class Cipher {
|
class Cipher {
|
||||||
private byte[] Key = new byte[512 / 8];
|
private byte[] Key = new byte[512 / 8];
|
||||||
private byte[] State = new byte[256];
|
private byte[] State = new byte[256];
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Square;
|
using Square;
|
||||||
|
|
||||||
namespace Server.Encryption {
|
namespace CircleScape.Encryption {
|
||||||
class KeyExchange {
|
class KeyExchange {
|
||||||
private BigInteger Secret;
|
private BigInteger Secret;
|
||||||
public BigInteger Generator { get; private set; } = 2;
|
public BigInteger Generator { get; private set; } = 2;
|
||||||
|
@ -22,7 +22,12 @@ namespace Server.Encryption {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Packet GenerateRequestPacket() {
|
public Packet GenerateRequestPacket() {
|
||||||
return new Packet(Packet.kId.KeyExchange, Generator.ToHexString(), Modulus.ToHexString(), BigInteger.ModPow(Generator, Secret, Modulus).ToHexString());
|
return new Packet(
|
||||||
|
Packet.kId.KeyExchange,
|
||||||
|
Generator.ToHexString(),
|
||||||
|
Modulus.ToHexString(),
|
||||||
|
BigInteger.ModPow(Generator, Secret, Modulus).ToHexString()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigInteger ParseResponsePacket(Packet packet) {
|
public BigInteger ParseResponsePacket(Packet packet) {
|
||||||
|
|
|
@ -4,22 +4,24 @@ using System.Data.SQLite;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Server.DAL;
|
using CircleScape.DAL;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Square;
|
using Square;
|
||||||
|
|
||||||
namespace Server {
|
namespace CircleScape {
|
||||||
class Entrypoint {
|
class Entrypoint {
|
||||||
static void Main(string[] args) {
|
static void Main(string[] args) {
|
||||||
var server = new Kneesocks.Server<PendingConnection>(6770, PoolManager.Pending);
|
var server = new Kneesocks.Server<PendingConnection>(6770, PoolManager.Pending);
|
||||||
server.Start();
|
server.Start();
|
||||||
|
|
||||||
while(true) {
|
/*while(true) {
|
||||||
var send = Console.ReadLine();
|
var send = Console.ReadLine();
|
||||||
PoolManager.Pending.Broadcast(Encoding.UTF8.GetBytes(send));
|
PoolManager.Pending.Broadcast(Encoding.UTF8.GetBytes(send));
|
||||||
|
|
||||||
// logic processing loop
|
// logic processing loop
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
Console.ReadLine();
|
||||||
|
|
||||||
server.Stop();
|
server.Stop();
|
||||||
PoolManager.Dispose();
|
PoolManager.Dispose();
|
||||||
|
|
|
@ -156,13 +156,13 @@ namespace Kneesocks {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadIfNotNull(ref byte[] buffer, int length) {
|
private void ReadIfNotNull(ref byte[] buffer, int length) {
|
||||||
buffer = buffer == null ? Buffer.AttemptRead(length)
|
buffer = buffer ?? Buffer.AttemptRead(length)
|
||||||
: buffer;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReadIfNotNull(ref byte[] buffer, string terminator) {
|
private void ReadIfNotNull(ref byte[] buffer, string terminator) {
|
||||||
buffer = buffer == null ? Buffer.AttemptRead(terminator)
|
buffer = buffer ?? Buffer.AttemptRead(terminator)
|
||||||
: buffer;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Parse() {
|
internal void Parse() {
|
||||||
|
|
|
@ -85,9 +85,13 @@ namespace Kneesocks {
|
||||||
| (IsMasked ? 0x80 : 0x0));
|
| (IsMasked ? 0x80 : 0x0));
|
||||||
|
|
||||||
if(headerLengthFirstByte >= 0x7E) {
|
if(headerLengthFirstByte >= 0x7E) {
|
||||||
var upperBound = headerLengthFirstByte == 0x7E ? 2 : 8;
|
var lengthBytes =
|
||||||
for(var i = 0; i < upperBound; ++i)
|
headerLengthFirstByte == 0x7E
|
||||||
returnValue[2 + i] |= (byte)((bodySize >> (8*(upperBound - i))) & 0xFF);
|
? ((UInt16)bodySize).Pack()
|
||||||
|
: bodySize.Pack();
|
||||||
|
|
||||||
|
for(var i = 0; i < lengthBytes.Length; ++i)
|
||||||
|
returnValue[2 + i] = lengthBytes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsMasked)
|
if(IsMasked)
|
||||||
|
|
|
@ -51,8 +51,7 @@ namespace Kneesocks {
|
||||||
if(connected) {
|
if(connected) {
|
||||||
try {
|
try {
|
||||||
client.Parse();
|
client.Parse();
|
||||||
if(CheckIfConnected(client))
|
connected = CheckIfConnected(client);
|
||||||
connected = false;
|
|
||||||
} catch {
|
} catch {
|
||||||
connected = false;
|
connected = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Server {
|
namespace CircleScape {
|
||||||
class ActiveConnection : Kneesocks.Connection {
|
class ActiveConnection : Kneesocks.Connection {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Square;
|
using Square;
|
||||||
|
|
||||||
namespace Server {
|
namespace CircleScape {
|
||||||
class Packet {
|
class Packet {
|
||||||
public enum kId {
|
public enum kId {
|
||||||
KeyExchange = 0,
|
KeyExchange = 0,
|
||||||
|
@ -17,7 +17,7 @@ namespace Server {
|
||||||
get => new Packet { IsLegal = false };
|
get => new Packet { IsLegal = false };
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Packet FromRaw(byte[] raw) {
|
public static Packet FromBytes(byte[] raw) {
|
||||||
if(raw.Length < 3)
|
if(raw.Length < 3)
|
||||||
return ErrorPacket;
|
return ErrorPacket;
|
||||||
|
|
||||||
|
@ -82,11 +82,13 @@ namespace Server {
|
||||||
get => new Region(Regions[i]);
|
get => new Region(Regions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(object region) {
|
public Packet AddRegion(object region) {
|
||||||
if(region.GetType() == typeof(byte[]))
|
if(region.GetType() == typeof(byte[]))
|
||||||
Regions.Add((byte[])region);
|
Regions.Add((byte[])region);
|
||||||
else if(region.GetType() == typeof(string))
|
else if(region.GetType() == typeof(string))
|
||||||
Regions.Add(((string)region).GetBytes());
|
Regions.Add(((string)region).GetBytes());
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetBytes() {
|
public byte[] GetBytes() {
|
||||||
|
|
|
@ -6,15 +6,21 @@ using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Square;
|
using Square;
|
||||||
using Kneesocks;
|
using Kneesocks;
|
||||||
|
using CircleScape.Encryption;
|
||||||
|
|
||||||
namespace Server {
|
namespace CircleScape {
|
||||||
class PendingConnection : Connection {
|
class PendingConnection : Connection {
|
||||||
private DateTime ConnectionOpened;
|
private DateTime ConnectionOpened;
|
||||||
|
private KeyExchange Key;
|
||||||
|
private Cipher Encryptor;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected override void OnOpen() {
|
protected override void OnOpen() {
|
||||||
ConnectionOpened = DateTime.UtcNow;
|
ConnectionOpened = DateTime.UtcNow;
|
||||||
|
Key = new KeyExchange();
|
||||||
|
|
||||||
|
Send(Key.GenerateRequestPacket().GetBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnParse() {
|
protected override void OnParse() {
|
||||||
|
@ -24,6 +30,24 @@ namespace Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnReceive(byte[] data) {
|
protected override void OnReceive(byte[] data) {
|
||||||
|
var packet = Packet.FromBytes(data);
|
||||||
|
if(!packet.IsLegal) {
|
||||||
|
Disconnect(Frame.kClosingReason.ProtocolError, "Packet received was not legal.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(packet.Id) {
|
||||||
|
case Packet.kId.KeyExchange:
|
||||||
|
Key.ParseResponsePacket(packet);
|
||||||
|
if(!Key.Succeeded) {
|
||||||
|
Disconnect(Frame.kClosingReason.ProtocolError, "Could not exchange keys.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Encryptor = new Cipher(Key.PrivateKey);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine(Id + " says " + data.GetString());
|
Console.WriteLine(Id + " says " + data.GetString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
||||||
using Kneesocks;
|
using Kneesocks;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace Server {
|
namespace CircleScape {
|
||||||
static class PoolManager {
|
static class PoolManager {
|
||||||
private static Pool<PendingConnection> PendingConnectionsPool;
|
private static Pool<PendingConnection> PendingConnectionsPool;
|
||||||
private static Pool<ActiveConnection> ActiveConnectionsPool;
|
private static Pool<ActiveConnection> ActiveConnectionsPool;
|
||||||
|
|
Loading…
Reference in a new issue