diff --git a/protocol.md b/protocol.md index 8cd9cd6..5963cde 100644 --- a/protocol.md +++ b/protocol.md @@ -91,7 +91,7 @@ Communication between the master server and clients will be done over a WebSocke ID 2: Positive ACK
- Responder + [Encrypted] Responder @@ -110,7 +110,7 @@ Communication between the master server and clients will be done over a WebSocke ID 3: Negative ACK
- Responder + [Encrypted] Responder @@ -130,6 +130,25 @@ Communication between the master server and clients will be done over a WebSocke + + + + + + + + + + + + + + +
+ ID 4: Encryption Error
+ Responder +
#RegionType
1Error MessageString
+ #### Slave to Master @@ -174,7 +193,7 @@ Communication between the master server and clients will be done over a WebSocke diff --git a/server/Encryption/KeyExchange.cs b/server/Encryption/KeyExchange.cs index cf69e8b..268da0c 100644 --- a/server/Encryption/KeyExchange.cs +++ b/server/Encryption/KeyExchange.cs @@ -45,10 +45,7 @@ namespace SockScape.Encryption { var clientKey = BigInteger.ModPow(generator, Secret, modulus); PrivateKey = BigInteger.ModPow(serverKey, Secret, modulus); - return new Packet( - 1, - clientKey.ToHexString() - ); + return new Packet(1, clientKey.ToHexString()); } public BigInteger ParseResponsePacket(Packet packet) { diff --git a/server/Socks/MasterUdpClient.cs b/server/Socks/MasterUdpClient.cs index 9facb0f..4428635 100644 --- a/server/Socks/MasterUdpClient.cs +++ b/server/Socks/MasterUdpClient.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; @@ -11,12 +12,19 @@ using SockScape.Encryption; namespace SockScape { static class MasterUdpClient { private static Key Key; - public static Cipher Encryptor { get; private set; } + private static Cipher Encryptor; private static UdpClient Sock; private static Thread ListeningThread; private static bool IsOpen; - private static DateTime LastMessage; + + private static DateTime LastMessageOut; + private static TimeSpan DeltaLastOut + => DateTime.Now - LastMessageOut; + + private static DateTime LastMessageIn = new DateTime(0); + private static TimeSpan DeltaLastIn + => DateTime.Now - LastMessageIn; public static void Initialize() { if(IsOpen || ListeningThread != null) @@ -26,6 +34,7 @@ namespace SockScape { Sock = new UdpClient(Configuration.General["Master Addr"], port); Key = new Key(); + Encryptor = null; IsOpen = true; ListeningThread = new Thread(Listener); @@ -34,17 +43,39 @@ namespace SockScape { public static void Listener() { while(IsOpen) { + if(LastMessageIn.Ticks == 0 && DeltaLastOut.TotalSeconds > 10) + Send(new Packet(kIntraSlaveId.InitiationAttempt, Configuration.General["Master Secret"])); + + var endPoint = new IPEndPoint(0, 0); while(Sock.Available > 0) { - + var data = Sock.Receive(ref endPoint); + LastMessageIn = DateTime.Now; + + Packet packet = + Encryptor == null ? Packet.FromBytes(data) + : Packet.FromBytes(Encryptor.Parse(data)); + + switch((kIntraMasterId)packet.Id) { + case kIntraMasterId.KeyExchange: + var responsePacket = Key.ParseRequestPacket(packet); + Encryptor = new Cipher(Key.PrivateKey); + if(responsePacket != null) + Send(responsePacket); + + else + LastMessageIn = new DateTime(0); + break; + } } Thread.Sleep(1); } } - public static void Send(byte[] message) { + public static void Send(Packet packet) { + var message = packet.GetBytes(); Sock.Send(message, message.Length); - LastMessage = DateTime.Now; + LastMessageOut = DateTime.Now; } public static void Close() { diff --git a/server/Socks/MasterUdpServer.cs b/server/Socks/MasterUdpServer.cs index 756f6d0..9e51355 100644 --- a/server/Socks/MasterUdpServer.cs +++ b/server/Socks/MasterUdpServer.cs @@ -37,7 +37,7 @@ namespace SockScape { public static void Listener() { while(IsOpen) { - IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); + IPEndPoint endPoint = new IPEndPoint(0, 0); while(Sock.Available > 0) { var data = Sock.Receive(ref endPoint); var client = endPoint.ToString(); @@ -51,11 +51,10 @@ namespace SockScape { if(packet == null) break; - - byte[] sendBuffer; - switch((kIntraMasterId)packet.Id) { - case kIntraMasterId.InitiationAttempt: - if(packet.RegionCount != 1) + + switch((kIntraSlaveId)packet.Id) { + case kIntraSlaveId.InitiationAttempt: + if(packet.RegionCount != 1 || IsProspectConnected(client)) break; if(packet[0] == Configuration.General["Master Secret"]) { @@ -66,12 +65,11 @@ namespace SockScape { Key = key }; - sendBuffer = key.GenerateRequestPacket().GetBytes(); - Sock.Send(sendBuffer, sendBuffer.Length, endPoint); + Send(key.GenerateRequestPacket(), endPoint); } break; - case kIntraMasterId.KeyExchange: + case kIntraSlaveId.KeyExchange: if(!IsProspectConnected(client)) break; @@ -84,11 +82,11 @@ namespace SockScape { Prospects.Remove(client); break; - case kIntraMasterId.StatusUpdate: + case kIntraSlaveId.StatusUpdate: if(!IsClientConnected(client) || packet.RegionCount < 1) break; - + break; } } @@ -99,6 +97,11 @@ namespace SockScape { } } + private static void Send(Packet packet, IPEndPoint client) { + var message = packet.GetBytes(); + Sock.Send(message, message.Length, client); + } + public static void Close() { IsOpen = false; ListeningThread.Join(); @@ -115,11 +118,15 @@ namespace SockScape { } private static Packet PositiveAck(byte id) { - return new Packet((int)kIntraMasterAckId.PositiveAck, new { id }); + return new Packet(kIntraMasterId.PositiveAck, id); } - private static Packet NegativeAck(byte id, string message) { - return new Packet((int)kIntraMasterAckId.NegativeAck, new { id, message }); + private static Packet NegativeAck(byte id, string message = "") { + return new Packet(kIntraMasterId.NegativeAck, id, message); + } + + private static Packet EncryptionError(string message = "A general encryption error has occurred.") { + return new Packet(kIntraMasterId.EncryptionError, message); } class Client { diff --git a/server/Socks/Protocols/IntraMasterIds.cs b/server/Socks/Protocols/IntraMasterIds.cs index 3e952a1..e980d0e 100644 --- a/server/Socks/Protocols/IntraMasterIds.cs +++ b/server/Socks/Protocols/IntraMasterIds.cs @@ -5,14 +5,16 @@ using System.Text; using System.Threading.Tasks; namespace SockScape { - public enum kIntraMasterId { + public enum kIntraSlaveId { InitiationAttempt = 0, KeyExchange, StatusUpdate } - public enum kIntraMasterAckId { - PositiveAck = 1, - NegativeAck + public enum kIntraMasterId { + KeyExchange = 1, + PositiveAck, + NegativeAck, + EncryptionError } } diff --git a/server/Socks/Protocols/Packet.cs b/server/Socks/Protocols/Packet.cs index 55e7da3..5610c24 100644 --- a/server/Socks/Protocols/Packet.cs +++ b/server/Socks/Protocols/Packet.cs @@ -65,7 +65,15 @@ namespace SockScape { protected Packet() { } + public Packet(Enum id, params object[] regions) { + Initialize((int)Convert.ChangeType(id, id.GetTypeCode()), regions); + } + public Packet(int id, params object[] regions) { + Initialize(id, regions); + } + + private void Initialize(int id, object[] regions) { Id = id; foreach(var region in regions)
ID 2: Status Update
- Blind Requester + [Encrypted] Blind Requester