diff --git a/.gitignore b/.gitignore
index d0993a7..2ea9a5f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -304,3 +304,4 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
+server/config.ini
diff --git a/protocol.md b/protocol.md
index 185852b..49244b9 100644
--- a/protocol.md
+++ b/protocol.md
@@ -36,6 +36,8 @@ All numbers, unless otherwise specified, are the string representation of a base
A packet ID may have a specific "direction" of communication, in that an endpoint may either act as a _requester_ or a _responder_. A _requester_ is an endpoint that drives all of the communication on that specific packet ID, while the _responder_ is responsible for providing a timely response to the requests it receives. A _responder_ for a specific packet ID should never send that packet ID unsolicited; either the packet will be ignored or the other endpoint will close the connection. Any packet ID marked as bidirectional may be initiated by either endpoint at any time.
+A _blind requester_ is an endpoint that sends out a packet of a certain ID and either does not expect a response or expects a response on a different packet ID.
+
#### Server to Client
TODO: populate
@@ -59,7 +61,80 @@ Communication between the master server and clients will be done over a WebSocke
- ID 0: Key Exchange
+ ID 1: Key Exchange
+ Requester (resp. StM ID 0)
+ |
+
+
+ # |
+ Region |
+ Type |
+
+
+ 1 |
+ Generator |
+ Big Int |
+
+
+ 2 |
+ Modulus |
+ Big Int |
+
+
+ 3 |
+ Server Key |
+ Big Int |
+
+
+
+#### Slave to Master
+
+
+
+
+ ID 0: Initiation Attempt
+ Blind Requester
+ |
+
+
+ # |
+ Region |
+ Type |
+
+
+ 1 |
+ Secret |
+ String |
+
+
+
+
+
+
+ ID 1: Key Exchange
+ Responder
+ |
+
+
+ # |
+ Region |
+ Type |
+
+
+ 1 |
+ Client Key |
+ Big Int |
+
+
+
+### Master/Client Packet IDs
+
+#### Master to Client
+
+
+
+
+ ID 1: Key Exchange
Requester
|
@@ -88,7 +163,7 @@ Communication between the master server and clients will be done over a WebSocke
- ID 1: Login Attempt
+ ID 2: Login Attempt
[Encrypted] Responder
|
@@ -112,7 +187,7 @@ Communication between the master server and clients will be done over a WebSocke
- ID 2: Registration Attempt
+ ID 3: Registration Attempt
[Encrypted] Responder
|
@@ -133,12 +208,12 @@ Communication between the master server and clients will be done over a WebSocke
-#### Slave to Master
+#### Client to Master
- ID 0: Key Exchange
+ ID 1: Key Exchange
Responder
|
@@ -149,15 +224,15 @@ Communication between the master server and clients will be done over a WebSocke
1 |
- Client Key |
- Big Int |
+ Secret |
+ String |
- ID 1: Login Attempt
+ ID 2: Login Attempt
[Encrypted] Requester
|
@@ -181,7 +256,7 @@ Communication between the master server and clients will be done over a WebSocke
- ID 2: Registration Attempt
+ ID 3: Registration Attempt
[Encrypted] Requester
|
@@ -207,12 +282,6 @@ Communication between the master server and clients will be done over a WebSocke
-### Master/Client Packet IDs
-
-#### Master to Client
-
-#### Client to Master
-
## Sockstamps
Because epoch time is not standardized across systems, an intermediate layer of date/time transmission must be used between the client and server so as to handle time dependent interactions. Therefore, a "sockstamp" will be used in place of the context-dependent implementations of epoch time.
diff --git a/server/2config.ini b/server/2config.ini
new file mode 100644
index 0000000..00be106
--- /dev/null
+++ b/server/2config.ini
@@ -0,0 +1,34 @@
+[General]
+; determines if this server instance should run the master server
+ Run Master = false
+
+; address and port of the master server
+;; if master server is in this instance, addr should be localhost
+;; and port determines what port the master server runs on
+Master Addr = localhost
+Master Port = 16670
+
+; this value used if the max users isn't specified in a server instance
+ Max Users = 100
+
+; url to a web page that prints out the public ip address of the requester
+ Ip Checker = http://aroltd.com/ip.php
+
+[Database]
+ Server = aroltd.com
+Username = alec
+Password = Buddyman5
+Database = scape
+
+[Server]
+ Id = 1
+ Port = 6770
+Max Users = 300
+
+[Server]
+ Id = 2
+ Port = 6780
+
+[Server]
+ Id = 3
+ Port = 6790
\ No newline at end of file
diff --git a/server/App.config b/server/App.config
index c5270de..eb0f533 100644
--- a/server/App.config
+++ b/server/App.config
@@ -17,7 +17,6 @@
-
diff --git a/server/Configuration.cs b/server/Configuration.cs
index 4a35fea..b3f5958 100644
--- a/server/Configuration.cs
+++ b/server/Configuration.cs
@@ -24,6 +24,17 @@ namespace SockScape {
}
},
+ new SectionRules {
+ Name = "Database",
+ Required = true,
+ RequiredFields = new string[] {
+ "Server",
+ "Username",
+ "Password",
+ "Database"
+ }
+ },
+
new SectionRules {
Name = "Server",
AllowMultiple = true,
@@ -47,6 +58,12 @@ namespace SockScape {
}
}
+ public static Instance Database {
+ get {
+ return Settings["Database"][0];
+ }
+ }
+
public static Section Servers {
get {
return Settings["Server"];
diff --git a/server/DAL/ScapeDb.cs b/server/DAL/ScapeDb.cs
index 3f1fc56..81005f0 100644
--- a/server/DAL/ScapeDb.cs
+++ b/server/DAL/ScapeDb.cs
@@ -1,9 +1,10 @@
-namespace SockScape.DAL {
- using System;
- using System.Data.Entity;
- using System.ComponentModel.DataAnnotations.Schema;
- using System.Linq;
+using System;
+using System.Data.Entity;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
+using Config = SockScape.Configuration;
+namespace SockScape.DAL {
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public partial class ScapeDb : DbContext {
static ScapeDb() {
@@ -11,7 +12,11 @@ namespace SockScape.DAL {
}
public ScapeDb()
- : base("name=ScapeDbDebug")
+ : base("server="+ Config.Database["Server"]
+ +";user id="+ Config.Database["Username"]
+ +";password="+ Config.Database["Password"]
+ +";persistsecurityinfo=True;"
+ +"database="+ Config.Database["Database"])
{
}
diff --git a/server/Encryption/KeyExchange.cs b/server/Encryption/KeyExchange.cs
index 764109b..605a3ce 100644
--- a/server/Encryption/KeyExchange.cs
+++ b/server/Encryption/KeyExchange.cs
@@ -23,21 +23,43 @@ namespace SockScape.Encryption {
public Packet GenerateRequestPacket() {
return new Packet(
- Packet.kId.KeyExchange,
+ 1,
Generator.ToHexString(),
Modulus.ToHexString(),
BigInteger.ModPow(Generator, Secret, Modulus).ToHexString()
);
}
+ public Packet ParseRequestPacket(Packet packet) {
+ if(packet.Id != 1 || packet.RegionCount != 3)
+ return null;
+
+ bool check = BigInteger.TryParse(packet[0], NumberStyles.HexNumber,
+ NumberFormatInfo.InvariantInfo, out BigInteger generator);
+ check &= BigInteger.TryParse(packet[1], NumberStyles.HexNumber,
+ NumberFormatInfo.InvariantInfo, out BigInteger modulus);
+ check &= BigInteger.TryParse(packet[2], NumberStyles.HexNumber,
+ NumberFormatInfo.InvariantInfo, out BigInteger serverKey);
+
+ if(!check)
+ return null;
+
+ var clientKey = BigInteger.ModPow(generator, Secret, modulus);
+ PrivateKey = BigInteger.ModPow(serverKey, Secret, modulus);
+ return new Packet(
+ 1,
+ clientKey.ToHexString()
+ );
+ }
+
public BigInteger ParseResponsePacket(Packet packet) {
- if(packet.Id != Packet.kId.KeyExchange || packet.RegionCount != 1)
+ if(packet.Id != 1 || packet.RegionCount != 1)
return -1;
- if(!BigInteger.TryParse(packet[0], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out BigInteger ClientKey))
+ if(!BigInteger.TryParse(packet[0], NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out BigInteger clientKey))
return -1;
- return (PrivateKey = BigInteger.ModPow(ClientKey, Secret, Modulus));
+ return (PrivateKey = BigInteger.ModPow(clientKey, Secret, Modulus));
}
}
}
diff --git a/server/Entrypoint.cs b/server/Entrypoint.cs
index b85e394..fd9bd2e 100644
--- a/server/Entrypoint.cs
+++ b/server/Entrypoint.cs
@@ -31,8 +31,6 @@ namespace SockScape {
servers.Add(server["Id"], new Server((ushort)server["Port"], pool, server));
}
-
-
//var server = new Server(6770, PoolManager.Pending);
//server.Start();
diff --git a/server/SockScape.csproj b/server/SockScape.csproj
index 417fc46..3a01b33 100644
--- a/server/SockScape.csproj
+++ b/server/SockScape.csproj
@@ -7,7 +7,7 @@
{438DBAC1-BA37-40BB-9CCE-0FE1F23C6DC5}
Exe
Properties
- CircleScape
+ SockScape
server
v4.6
512
@@ -87,7 +87,10 @@
-
+
+
+
+
@@ -96,10 +99,6 @@
Designer
-
- App.config
- Designer
-
Designer
App.config
diff --git a/server/Socks/MasterConnection.cs b/server/Socks/MasterConnection.cs
index b65d0f7..5af8b9f 100644
--- a/server/Socks/MasterConnection.cs
+++ b/server/Socks/MasterConnection.cs
@@ -5,9 +5,54 @@ using System.Text;
using System.Threading.Tasks;
using Kneesocks;
using Glove;
+using SockScape.Encryption;
-namespace SockScape.Socks {
+namespace SockScape {
class MasterConnection : Connection {
+ private Key Key;
+ public Cipher Encryptor { get; private set; } = null;
+
+ protected override void OnOpen() {
+ Key = new Key();
+ Send(Key.GenerateRequestPacket().GetBytes());
+ }
+ protected override void OnParse() {
+
+ }
+
+ protected override void OnReceive(byte[] data) {
+ Packet packet =
+ Encryptor == null ? Packet.FromBytes(data)
+ : Packet.FromBytes(Encryptor.Parse(data));
+
+ if(packet == null) {
+ Disconnect(Frame.kClosingReason.ProtocolError, "Packet received was not legal.");
+ return;
+ }
+
+ switch((kInterMasterId)packet.Id) {
+ case kInterMasterId.KeyExchange:
+ Key.ParseResponsePacket(packet);
+ if(!Key.Succeeded) {
+ Disconnect(Frame.kClosingReason.ProtocolError, "Could not exchange keys.");
+ return;
+ }
+
+ Encryptor = new Cipher(Key.PrivateKey);
+ break;
+ case kInterMasterId.LoginAttempt:
+
+ break;
+ case kInterMasterId.RegistrationAttempt:
+
+ break;
+ default:
+ Disconnect(Frame.kClosingReason.ProtocolError, "Packet ID could not be understood at this time.");
+ break;
+ }
+
+ Console.WriteLine(Id + " says " + data.GetString());
+ }
}
}
diff --git a/server/Socks/MasterUdpServer.cs b/server/Socks/MasterUdpServer.cs
index 3b3d986..4a5fafd 100644
--- a/server/Socks/MasterUdpServer.cs
+++ b/server/Socks/MasterUdpServer.cs
@@ -28,7 +28,7 @@ namespace SockScape.Socks {
public static void Listener() {
while(IsOpen) {
while(Sock.Available > 0) {
-
+
}
Thread.Sleep(1);
diff --git a/server/Socks/PlayerConnection.cs b/server/Socks/PlayerConnection.cs
index 804fcab..567548c 100644
--- a/server/Socks/PlayerConnection.cs
+++ b/server/Socks/PlayerConnection.cs
@@ -11,14 +11,9 @@ using SockScape.Encryption;
namespace SockScape {
class PlayerConnection : Connection {
private DateTime ConnectionOpened;
- private Key Key;
- public Cipher Encryptor { get; private set; } = null;
protected override void OnOpen() {
ConnectionOpened = DateTime.UtcNow;
- Key = new Key();
-
- Send(Key.GenerateRequestPacket().GetBytes());
}
protected override void OnParse() {
@@ -28,28 +23,14 @@ namespace SockScape {
}
protected override void OnReceive(byte[] data) {
- Packet packet =
- Encryptor == null ? Packet.FromBytes(data)
- : Packet.FromBytes(Encryptor.Parse(data));
+ Packet packet = Packet.FromBytes(data);
if(packet == null) {
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;
- case Packet.kId.LoginAttempt:
-
- break;
+ switch((kClientServerId)packet.Id) {
default:
Disconnect(Frame.kClosingReason.ProtocolError, "Packet ID could not be understood at this time.");
break;
diff --git a/server/Socks/Protocols/ClientServerIds.cs b/server/Socks/Protocols/ClientServerIds.cs
new file mode 100644
index 0000000..21386ce
--- /dev/null
+++ b/server/Socks/Protocols/ClientServerIds.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SockScape {
+ public enum kClientServerId {
+
+ }
+}
diff --git a/server/Socks/Protocols/InterMasterIds.cs b/server/Socks/Protocols/InterMasterIds.cs
new file mode 100644
index 0000000..f51e7fc
--- /dev/null
+++ b/server/Socks/Protocols/InterMasterIds.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SockScape {
+ public enum kInterMasterId {
+ KeyExchange = 1,
+ LoginAttempt,
+ RegistrationAttempt
+ }
+}
diff --git a/server/Socks/Protocols/IntraMasterIds.cs b/server/Socks/Protocols/IntraMasterIds.cs
new file mode 100644
index 0000000..2d24c58
--- /dev/null
+++ b/server/Socks/Protocols/IntraMasterIds.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SockScape {
+ public enum kIntraMasterId {
+ InitiationAttempt = 0,
+ KeyExchange
+ }
+}
diff --git a/server/Socks/Packet.cs b/server/Socks/Protocols/Packet.cs
similarity index 88%
rename from server/Socks/Packet.cs
rename to server/Socks/Protocols/Packet.cs
index 0ddddcc..a98abf7 100644
--- a/server/Socks/Packet.cs
+++ b/server/Socks/Protocols/Packet.cs
@@ -9,24 +9,16 @@ namespace SockScape {
class Packet {
private static readonly byte[] MagicNumber = { 0xF0, 0x9F, 0xA6, 0x91 };
- public enum kId {
- KeyExchange = 0,
- LoginAttempt,
- RegistrationAttempt
- }
-
public static Packet FromBytes(byte[] raw) {
if(raw.Length < 7)
return null;
Packet packet = new Packet();
- if(!Enum.IsDefined(typeof(kId), (int)raw[4]))
- return null;
if(!raw.Subset(0, 4).SequenceEqual(MagicNumber))
return null;
- packet.Id = (kId)raw[4];
+ packet.Id = raw[4];
var regionCount = raw[5];
var regionLengths = new List();
var headerPtr = 6;
@@ -66,15 +58,14 @@ namespace SockScape {
}
private List Regions = new List();
- public kId Id { get; private set; } = kId.KeyExchange;
- public bool IsLegal { get; private set; } = true;
+ public int Id { get; private set; }
public int RegionCount {
get => Regions.Count;
}
- private Packet() { }
+ protected Packet() { }
- public Packet(kId id, params object[] regions) {
+ public Packet(int id, params object[] regions) {
Id = id;
foreach(var region in regions)
@@ -95,9 +86,6 @@ namespace SockScape {
}
public byte[] GetBytes() {
- if(!IsLegal)
- return null;
-
var header = new List();
header.AddRange(MagicNumber);
header.Add((byte)Id);
diff --git a/server/config.ini b/server/config.ini
index b4dc288..00be106 100644
--- a/server/config.ini
+++ b/server/config.ini
@@ -13,6 +13,12 @@ Master Port = 16670
; url to a web page that prints out the public ip address of the requester
Ip Checker = http://aroltd.com/ip.php
+
+[Database]
+ Server = aroltd.com
+Username = alec
+Password = Buddyman5
+Database = scape
[Server]
Id = 1