diff --git a/client/src/Connection.ts b/client/src/Connection.ts new file mode 100644 index 0000000..aa742e9 --- /dev/null +++ b/client/src/Connection.ts @@ -0,0 +1,17 @@ +class Connection { + private static Sock: WebSocket = null; + private static _IsOpen: boolean = false; + public static get IsOpen(): boolean { + return Connection._IsOpen; + } + + public static Initialize(): void { + Connection.Sock + } + + public static Close(): void { + + } + + private static +} \ No newline at end of file diff --git a/client/src/Crypto.ts b/client/src/Crypto.ts new file mode 100644 index 0000000..e69de29 diff --git a/client/src/Extensions.ts b/client/src/Extensions.ts new file mode 100644 index 0000000..52149f5 --- /dev/null +++ b/client/src/Extensions.ts @@ -0,0 +1,140 @@ +/// + +// ** STRING EXTENSIONS ** \\ + +interface String { + ReplaceAll(needle: string[], replace: string, ignoreCase?: boolean): string; + ReplaceAll(needle: string[], replace: string[], ignoreCase?: boolean): string; + ReplaceAll(needle: string, replace: string, ignoreCase?: boolean): string; + Contains(needle: string, ignoreCase?: boolean): boolean; + + StripCharacters(chars: string): string; + + HasUnicodeCharacters(): boolean; + ToByteArray(): Uint8Array; + ByteLength(): number; +} + +String.prototype.ReplaceAll = function(needle: any, replace: any, ignoreCase: boolean = false): string { + if((typeof needle) == "string") + return this.replace(new RegExp(needle.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignoreCase?"gi":"g")),(typeof(replace)=="string")?replace.replace(/\$/g,"$$$$"):replace); + else { + var retval = this; + for(var i in needle) { + if((typeof replace) == "string") + retval = retval.replaceAll(needle[i], replace, ignoreCase); + else + retval = retval.replaceAll(needle[i], replace[i], ignoreCase); + } + return retval; + } +}; + +String.prototype.Contains = function(needle: string, ignoreCase: boolean = false): boolean { + return ignoreCase + ? this.toLowerCase().indexOf(needle.toLowerCase()) != -1 + : this.indexOf(needle) != -1; +}; + +String.prototype.StripCharacters = function(chars: string) { + var copy = this; + if(chars != "") + copy = copy.replaceAll(chars.split(""), ""); + + return copy; +}; + +String.prototype.HasUnicodeCharacters = function() { + for(var i = 0; i < this.length; i++) { + if(this.charCodeAt(i) > 127) return true; + } + return false; +}; + +String.prototype.ByteLength = function() { + return utf8.encode(this).length; +}; + +String.prototype.ToByteArray = function() { + var str = utf8.encode(this); + var ret = new Uint8Array(str.length); + for(var i = 0; i < str.length; i++) + ret[i] = str.charCodeAt(i); + + return ret; +}; + + +// ** DATE EXTENSIONS ** \\ + +interface DateConstructor { + unixNow(): number; +} + +interface Date { + toUnixTime(): number; + toDateTimeString(): string; +} + +Date.unixNow = function() { + return (new Date()).toUnixTime(); +}; + +Date.prototype.toUnixTime = function() { + return Math.floor(this.getTime()/1000); +}; + +Date.prototype.toDateTimeString = function() { + return this.toDateString() +" @ "+ this.getHours().zeroPad() +":"+ this.getMinutes().zeroPad() +":"+ this.getSeconds().zeroPad(); +}; + +Date.prototype.toTimeString = function() { + return this.getHours().zeroPad() +":"+ this.getMinutes().zeroPad() +":"+ this.getSeconds().zeroPad(); +}; + + +// ** NUMBER EXTENSIONS ** \\ + +interface Number { + zeroPad(mag?: number): string; + packBytes(bytes: number): Uint8Array; +} + +Number.prototype.zeroPad = function(mag: number = 1): string { + var ret = ""+ this; + for(; this < Math.pow(10, mag) && mag != 0; --mag) + ret = "0" + ret; + return ret; +}; + +Number.prototype.packBytes = function(bytes: number) { + var ret = new Uint8Array(bytes); + for(var i = 0; i < bytes; i++) + ret[i] = (this & (0xFF << 8 * (bytes - 1 - i))) >>> 8 * (bytes - 1 - i); + return ret; +}; + + +// ** UINT8ARRAY EXTENSIONS ** \\ + +interface Uint8Array { + unpackBytes(): number; + toString(): string; +} + +Uint8Array.prototype.unpackBytes = function() { + var ret = 0; + for(var i = 0; i < this.length; i++) + ret = ret | ((this[i] & 0xFF) << 8*(this.length - 1 - i)); + return ret; +}; + +Uint8Array.prototype.toString = function() { + var chunkSize = 10000; + var raw = ""; + for(var i = 0;; i++) { + if(this.length < chunkSize*i) break; + raw += String.fromCharCode.apply(null, this.subarray(chunkSize*i, chunkSize*i + chunkSize)); + } + return utf8.decode(raw); +}; \ No newline at end of file diff --git a/client/src/Packet.ts b/client/src/Packet.ts new file mode 100644 index 0000000..21c6f41 --- /dev/null +++ b/client/src/Packet.ts @@ -0,0 +1,23 @@ +const enum kPacketId { + KeyExchange = 0, + LoginAttempt, + RegistrationAttempt +} + +class Packet { + private _Id: kPacketId; + public get Id(): kPacketId { + return this._Id; + } + + private _IsLegal: boolean = true; + public get IsLegal(): boolean { + return this._IsLegal; + } + + private Regions: Uint8Array[] = []; + + public get RegionCount(): number { + return this.Regions.length; + } +} \ No newline at end of file diff --git a/server/CircleScape.csproj b/server/CircleScape.csproj index 5ed0844..5e379f3 100644 --- a/server/CircleScape.csproj +++ b/server/CircleScape.csproj @@ -38,6 +38,10 @@ OnBuildSuccess + + + + packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll diff --git a/server/CircleScape.sln b/server/CircleScape.sln index 3efd8d2..e55c872 100644 --- a/server/CircleScape.sln +++ b/server/CircleScape.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26403.7 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CircleScape", "CircleScape.csproj", "{438DBAC1-BA37-40BB-9CCE-0FE1F23C6DC5}" EndProject diff --git a/server/DAL/ScapeDb.Context.cs b/server/DAL/ScapeDb.Context.cs index 8918cb4..d839c65 100644 --- a/server/DAL/ScapeDb.Context.cs +++ b/server/DAL/ScapeDb.Context.cs @@ -7,7 +7,7 @@ // //------------------------------------------------------------------------------ -namespace CircleScape.DAL +namespace Server.DAL { using System; using System.Data.Entity; diff --git a/server/DAL/Sessions.cs b/server/DAL/Sessions.cs index 47c442c..fd63ee1 100644 --- a/server/DAL/Sessions.cs +++ b/server/DAL/Sessions.cs @@ -7,7 +7,7 @@ // //------------------------------------------------------------------------------ -namespace CircleScape.DAL +namespace Server.DAL { using System; using System.Collections.Generic; diff --git a/server/DAL/Users.cs b/server/DAL/Users.cs index e8d1985..a8d3abc 100644 --- a/server/DAL/Users.cs +++ b/server/DAL/Users.cs @@ -7,7 +7,7 @@ // //------------------------------------------------------------------------------ -namespace CircleScape.DAL +namespace Server.DAL { using System; using System.Collections.Generic; diff --git a/server/Encryption/Cipher.cs b/server/Encryption/Cipher.cs index dafabea..2ae5392 100644 --- a/server/Encryption/Cipher.cs +++ b/server/Encryption/Cipher.cs @@ -3,34 +3,48 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Numerics; +using Square; -namespace CircleScape.Encryption { +namespace Server.Encryption { class Cipher { + private byte[] Key = new byte[512 / 8]; + private byte[] State = new byte[256]; - static void ksa(byte[] state, byte[] key) { - int i, j = 0, t; - for(i = 0; i < 256; ++i) - state[i] = (byte)i; + public Cipher(BigInteger key) { + int i = 0, j = 0; + State = State.Select(x => (byte)i++).ToArray(); + Key = Key.Select(x => (byte)0).ToArray(); + Array.Copy(key.ToByteArray(), Key, Key.Length); - for(i = 0; i < 256; ++i) { - j = (j + state[i] + key[i % key.Length]) % 256; - t = state[i]; - state[i] = state[j]; - state[j] = (byte)t; + for(i = 0; i < State.Length; ++i) { + j = (j + State[i] + Key[i % Key.Length]) % 256; + Utils.Swap(ref State[i], ref State[j]); } + + GenerateStream(1024); } - static void prga(byte[] state, byte[] cipher) { - int i = 0, j = 0, x, t; + private byte[] GenerateStream(long length) { + var stream = new byte[length]; + int i = 0, j = 0; - for(x = 0; x < cipher.Length; ++x) { + for(long x = 0; x < length; ++x) { i = (i + 1) % 256; - j = (j + state[i]) % 256; - t = state[i]; - state[i] = state[j]; - state[j] = (byte)t; - cipher[x] = state[(state[i] + state[j]) % 256]; + j = (j + State[i]) % 256; + Utils.Swap(ref State[i], ref State[j]); + stream[x] = State[(State[i] + State[j]) % 256]; } + + return stream; + } + + public byte[] Parse(byte[] data) { + var stream = GenerateStream(data.LongLength); + for(long i = 0; i < data.LongLength; ++i) + data[i] ^= stream[i]; + + return data; } } } diff --git a/server/Encryption/KeyExchange.cs b/server/Encryption/KeyExchange.cs index 15e5516..2594069 100644 --- a/server/Encryption/KeyExchange.cs +++ b/server/Encryption/KeyExchange.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using System.Numerics; using Square; -namespace CircleScape.Encryption { +namespace Server.Encryption { class KeyExchange { private BigInteger Secret; public BigInteger Generator { get; private set; } = 2; diff --git a/server/Entrypoint.cs b/server/Entrypoint.cs index 3fe0de4..c42f420 100644 --- a/server/Entrypoint.cs +++ b/server/Entrypoint.cs @@ -4,11 +4,11 @@ using System.Data.SQLite; using System.Linq; using System.Text; using System.Threading.Tasks; -using CircleScape.DAL; +using Server.DAL; using System.Numerics; using Square; -namespace CircleScape { +namespace Server { class Entrypoint { static void Main(string[] args) { var server = new Kneesocks.Server(6770, PoolManager.Pending); diff --git a/server/Libraries/Square/General.cs b/server/Libraries/Square/General.cs new file mode 100644 index 0000000..8c354de --- /dev/null +++ b/server/Libraries/Square/General.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Square { + public static class Utils { + public static void Swap(ref T a, ref T b) { + T c = a; + a = b; + b = c; + } + } +} diff --git a/server/Libraries/Square/Square.csproj b/server/Libraries/Square/Square.csproj index 47a502e..5a2bcd5 100644 --- a/server/Libraries/Square/Square.csproj +++ b/server/Libraries/Square/Square.csproj @@ -43,6 +43,7 @@ + diff --git a/server/Socks/ActiveConnection.cs b/server/Socks/ActiveConnection.cs index c3b475a..96342a0 100644 --- a/server/Socks/ActiveConnection.cs +++ b/server/Socks/ActiveConnection.cs @@ -5,7 +5,7 @@ using System.Net.Sockets; using System.Text; using System.Threading.Tasks; -namespace CircleScape { +namespace Server { class ActiveConnection : Kneesocks.Connection { } diff --git a/server/Socks/Packet.cs b/server/Socks/Packet.cs index 8c9331e..dcc00cc 100644 --- a/server/Socks/Packet.cs +++ b/server/Socks/Packet.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using Square; -namespace CircleScape { +namespace Server { class Packet { public enum kId { KeyExchange = 0, diff --git a/server/Socks/PendingConnection.cs b/server/Socks/PendingConnection.cs index 83ca828..8a1fb14 100644 --- a/server/Socks/PendingConnection.cs +++ b/server/Socks/PendingConnection.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Square; using Kneesocks; -namespace CircleScape { +namespace Server { class PendingConnection : Connection { private DateTime ConnectionOpened; diff --git a/server/Socks/PoolManager.cs b/server/Socks/PoolManager.cs index 4782cd6..091dad0 100644 --- a/server/Socks/PoolManager.cs +++ b/server/Socks/PoolManager.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Kneesocks; using System.Net.Sockets; -namespace CircleScape { +namespace Server { static class PoolManager { private static Pool PendingConnectionsPool; private static Pool ActiveConnectionsPool;