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>
|
||||
|
||||
<p><i>Details: <span id="errorText"></span></i></p>
|
||||
|
||||
<p>Please report this error to <a href="mailto:aleco@aroltd.com">aleco@aroltd.com</a>.
|
||||
<p>
|
||||
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>
|
||||
</body>
|
||||
</html>
|
|
@ -13,6 +13,7 @@ class Connection {
|
|||
|
||||
// FLAG replace hard coded url with one loaded from a config file
|
||||
Connection.sock = new WebSocket("ws://localhost:6770");
|
||||
Connection.sock.binaryType = "arraybuffer";
|
||||
|
||||
Connection.onOpenFunc = onOpen;
|
||||
Connection.sock.onopen = Connection.onOpen;
|
||||
|
@ -28,8 +29,10 @@ class Connection {
|
|||
}
|
||||
|
||||
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[1].toString());
|
||||
|
||||
switch(msg.id) {
|
||||
case kPacketId.KeyExchange:
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/// <reference path="FileCache.ts" />
|
||||
/// <reference path="Utilities.ts" />
|
||||
|
||||
class Entrypoint {
|
||||
private static initStatus = {
|
||||
fileCache: false
|
||||
|
@ -16,6 +13,8 @@ class Entrypoint {
|
|||
}
|
||||
|
||||
public static start(): void {
|
||||
Connection.open();
|
||||
|
||||
FileCache.initCache(
|
||||
// SUCCESS
|
||||
() => {
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/// <reference path="def/UTF8.d.ts" />
|
||||
|
||||
// ** STRING EXTENSIONS ** \\
|
||||
|
||||
interface String {
|
||||
|
@ -162,6 +160,8 @@ interface Uint8Array {
|
|||
|
||||
unpackFloat(offset?: number): number;
|
||||
unpackDouble(offset?: number): number;
|
||||
|
||||
toHexString(): string;
|
||||
}
|
||||
|
||||
Uint8Array.prototype.unpackInt16 = function(offset: number = 0): number {
|
||||
|
@ -203,3 +203,33 @@ Uint8Array.prototype.toString = function(): string {
|
|||
}
|
||||
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 stores = db.objectStoreNames;
|
||||
/*
|
||||
for(var i in stores)
|
||||
db.deleteObjectStore(stores[i]);
|
||||
db.deleteObjectStore(i);
|
||||
*/
|
||||
|
||||
db.createObjectStore("files", {keyPath: "name", autoIncrement: false});
|
||||
db.createObjectStore("metadata", {keyPath: "name", autoIncrement: false});
|
||||
|
|
|
@ -23,18 +23,26 @@ class Packet {
|
|||
public getRegionString(region: number): string {
|
||||
return this.getRegion(region).toString();
|
||||
}
|
||||
public addRegion(region: object): void {
|
||||
public addRegion(region: object): Packet {
|
||||
if(typeof region == "string")
|
||||
this._regions.push((<string>region).toByteArray());
|
||||
else if(region instanceof Uint8Array)
|
||||
this._regions.push(region);
|
||||
|
||||
this[this.regionCount-1] = this._regions[this.regionCount-1];
|
||||
return this;
|
||||
}
|
||||
|
||||
public Packet(id: kPacketId, regions: any[]) {
|
||||
this._id = id;
|
||||
private constructor() {}
|
||||
|
||||
public static create(id: kPacketId, regions: any[]): Packet {
|
||||
var packet = new Packet;
|
||||
packet._id = id;
|
||||
regions.forEach(region => {
|
||||
this.addRegion(region);
|
||||
packet.addRegion(region);
|
||||
});
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
public static fromBytes(bytes: Uint8Array): Packet {
|
||||
|
@ -58,7 +66,7 @@ class Packet {
|
|||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Server.DAL
|
||||
namespace CircleScape.DAL
|
||||
{
|
||||
using System;
|
||||
using System.Data.Entity;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Server.DAL
|
||||
namespace CircleScape.DAL
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace Server.DAL
|
||||
namespace CircleScape.DAL
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||
using System.Numerics;
|
||||
using Square;
|
||||
|
||||
namespace Server.Encryption {
|
||||
namespace CircleScape.Encryption {
|
||||
class Cipher {
|
||||
private byte[] Key = new byte[512 / 8];
|
||||
private byte[] State = new byte[256];
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||
using System.Numerics;
|
||||
using Square;
|
||||
|
||||
namespace Server.Encryption {
|
||||
namespace CircleScape.Encryption {
|
||||
class KeyExchange {
|
||||
private BigInteger Secret;
|
||||
public BigInteger Generator { get; private set; } = 2;
|
||||
|
@ -22,7 +22,12 @@ namespace Server.Encryption {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -4,22 +4,24 @@ using System.Data.SQLite;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Server.DAL;
|
||||
using CircleScape.DAL;
|
||||
using System.Numerics;
|
||||
using Square;
|
||||
|
||||
namespace Server {
|
||||
namespace CircleScape {
|
||||
class Entrypoint {
|
||||
static void Main(string[] args) {
|
||||
var server = new Kneesocks.Server<PendingConnection>(6770, PoolManager.Pending);
|
||||
server.Start();
|
||||
|
||||
while(true) {
|
||||
/*while(true) {
|
||||
var send = Console.ReadLine();
|
||||
PoolManager.Pending.Broadcast(Encoding.UTF8.GetBytes(send));
|
||||
|
||||
// logic processing loop
|
||||
}
|
||||
}*/
|
||||
|
||||
Console.ReadLine();
|
||||
|
||||
server.Stop();
|
||||
PoolManager.Dispose();
|
||||
|
|
|
@ -156,13 +156,13 @@ namespace Kneesocks {
|
|||
}
|
||||
|
||||
private void ReadIfNotNull(ref byte[] buffer, int length) {
|
||||
buffer = buffer == null ? Buffer.AttemptRead(length)
|
||||
: buffer;
|
||||
buffer = buffer ?? Buffer.AttemptRead(length)
|
||||
;
|
||||
}
|
||||
|
||||
private void ReadIfNotNull(ref byte[] buffer, string terminator) {
|
||||
buffer = buffer == null ? Buffer.AttemptRead(terminator)
|
||||
: buffer;
|
||||
buffer = buffer ?? Buffer.AttemptRead(terminator)
|
||||
;
|
||||
}
|
||||
|
||||
internal void Parse() {
|
||||
|
|
|
@ -85,9 +85,13 @@ namespace Kneesocks {
|
|||
| (IsMasked ? 0x80 : 0x0));
|
||||
|
||||
if(headerLengthFirstByte >= 0x7E) {
|
||||
var upperBound = headerLengthFirstByte == 0x7E ? 2 : 8;
|
||||
for(var i = 0; i < upperBound; ++i)
|
||||
returnValue[2 + i] |= (byte)((bodySize >> (8*(upperBound - i))) & 0xFF);
|
||||
var lengthBytes =
|
||||
headerLengthFirstByte == 0x7E
|
||||
? ((UInt16)bodySize).Pack()
|
||||
: bodySize.Pack();
|
||||
|
||||
for(var i = 0; i < lengthBytes.Length; ++i)
|
||||
returnValue[2 + i] = lengthBytes[i];
|
||||
}
|
||||
|
||||
if(IsMasked)
|
||||
|
|
|
@ -51,8 +51,7 @@ namespace Kneesocks {
|
|||
if(connected) {
|
||||
try {
|
||||
client.Parse();
|
||||
if(CheckIfConnected(client))
|
||||
connected = false;
|
||||
connected = CheckIfConnected(client);
|
||||
} catch {
|
||||
connected = false;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Net.Sockets;
|
|||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Server {
|
||||
namespace CircleScape {
|
||||
class ActiveConnection : Kneesocks.Connection {
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Square;
|
||||
|
||||
namespace Server {
|
||||
namespace CircleScape {
|
||||
class Packet {
|
||||
public enum kId {
|
||||
KeyExchange = 0,
|
||||
|
@ -17,7 +17,7 @@ namespace Server {
|
|||
get => new Packet { IsLegal = false };
|
||||
}
|
||||
|
||||
public static Packet FromRaw(byte[] raw) {
|
||||
public static Packet FromBytes(byte[] raw) {
|
||||
if(raw.Length < 3)
|
||||
return ErrorPacket;
|
||||
|
||||
|
@ -82,11 +82,13 @@ namespace Server {
|
|||
get => new Region(Regions[i]);
|
||||
}
|
||||
|
||||
public void AddRegion(object region) {
|
||||
public Packet AddRegion(object region) {
|
||||
if(region.GetType() == typeof(byte[]))
|
||||
Regions.Add((byte[])region);
|
||||
else if(region.GetType() == typeof(string))
|
||||
Regions.Add(((string)region).GetBytes());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte[] GetBytes() {
|
||||
|
|
|
@ -6,15 +6,21 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Square;
|
||||
using Kneesocks;
|
||||
using CircleScape.Encryption;
|
||||
|
||||
namespace Server {
|
||||
namespace CircleScape {
|
||||
class PendingConnection : Connection {
|
||||
private DateTime ConnectionOpened;
|
||||
private KeyExchange Key;
|
||||
private Cipher Encryptor;
|
||||
|
||||
|
||||
|
||||
protected override void OnOpen() {
|
||||
ConnectionOpened = DateTime.UtcNow;
|
||||
Key = new KeyExchange();
|
||||
|
||||
Send(Key.GenerateRequestPacket().GetBytes());
|
||||
}
|
||||
|
||||
protected override void OnParse() {
|
||||
|
@ -24,6 +30,24 @@ namespace Server {
|
|||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||
using Kneesocks;
|
||||
using System.Net.Sockets;
|
||||
|
||||
namespace Server {
|
||||
namespace CircleScape {
|
||||
static class PoolManager {
|
||||
private static Pool<PendingConnection> PendingConnectionsPool;
|
||||
private static Pool<ActiveConnection> ActiveConnectionsPool;
|
||||
|
|
Loading…
Reference in a new issue