예제 #1
0
        /// <summary>
        /// Received network packet (contains entity name, message,
        /// </summary>
        /// <returns>The entity.</returns>
        /// <param name="packet">Packet.</param>
        public ValidationError ValidateEntity(ClientMessage packet, byte[] hmac, byte[] packetRaw, bool ignoreConnected = false)
        {
            string ts = Helpers.GetTimestamp(DateTime.Now);

            if (ts != packet.Timestamp)
            {
                return(ValidationError.InvalidTime);
            }

            byte[] key = GenKey(seed1, selector);
            byte[] iv  = GenIV(seed2, selector);

            if (entities == null)
            {
                return(ValidationError.NotFound);
            }

            bool dbValidation = ValidateDecryption(entities, key, iv);

            if (!dbValidation)
            {
                return(ValidationError.NotFound);
            }
            if (ignoreConnected)
            {
                if (Program.server.clientHandlers.Contains(packet.Entity))
                {
                    return(ValidationError.AlreadyConnected);
                }
            }

            byte[] decripted = DecryptData(entities, key, iv);

            List <EntityClass> _entities = Helpers.FromByteArray <List <EntityClass> >(decripted);

            decripted = null;

            if (_entities.Any(m => m.EntityName == packet.Entity))
            {
                EntityClass storedEntity = _entities.First(m => m.EntityName == packet.Entity);
                byte[]      calcHMAC     = SHA256hmac.ComputeHMAC(packetRaw, storedEntity.Key);
                return(!SHA256hmac.CompareHMAC(hmac, calcHMAC) ? ValidationError.InvalidKey : ValidationError.NoError);
            }
            _entities = null;
            return(ValidationError.NotFound);
        }
예제 #2
0
        /// <summary>
        /// Handles all messages received by the client (except the first one)
        /// </summary>
        /// <param name="m">Packet without the byte length</param>
        /// <param name="clientHandler">Client handler.</param>
        static void Server_MessageReceived(byte[] m, ClientHandler clientHandler)
        {
            IPAddress ip = ((IPEndPoint)clientHandler.Socket.Client.RemoteEndPoint).Address;

            PacketType packetType = Server.DecodePacketType(m);

            Server.DeconstructPacket(m, out byte[] hmac, out ClientMessage message, out byte[] raw);

            if (enableDebug)
            {
                ReplaceWith("");
            }
            ProcessDebugMessage(string.Format("Message received from {0} ({1})", message.Entity, ip));

            // This step allows the verification of:
            // 1. if the entity is still accepted by the server
            // 2. if the hmac is corect
            Database.ValidationError validation = database.ValidateEntity(message, hmac, raw);

            switch (validation)
            {
            case Database.ValidationError.NoError:
                if (ClientOperations.RequestConnectedEntities.Value == message.Operation)
                {
                    RequestedEntitiesList(clientHandler);
                }
                else if (ClientOperations.Disconnect.Value == message.Operation)
                {
                    server.UserDisconnected(clientHandler.Entity);
                }
                else if (ClientOperations.RequestKeyNegotiation.Value == message.Operation)
                {
                    NegotiateKey(message, clientHandler);
                }
                else
                {
                    ServerCommand sv_cmd_invalid_operation = new ServerCommand
                    {
                        Command = ServerOperations.InvalidComand.Value
                    };
                    server.SendMessage(sv_cmd_invalid_operation,
                                       PacketType.ServerCommand,
                                       database.RetreiveEntityKey(clientHandler.Entity),
                                       clientHandler.Socket);
                }
                break;

            case Database.ValidationError.InvalidKey:
                ProcessDebugMessage(string.Format("HMAC for message from {0} ({1}) failed!", message.Entity, ip));
                ServerCommand sv_cmd_invalid_hmac = new ServerCommand
                {
                    Command = ServerOperations.InvalidHMAC.Value,
                    Message = string.Format("RECEIVED_HMAC={0}|COMPUTED_HMAC={1}", hmac.FromByteArrayToHex(), SHA256hmac.ComputeHMAC(raw, database.RetreiveEntityKey(clientHandler.Entity)).FromByteArrayToHex())
                };
                server.SendMessage(sv_cmd_invalid_hmac,
                                   PacketType.ServerCommand,
                                   DEFAULT_KEY.FromHexToByteArray(),
                                   clientHandler.Socket);
                break;

            case Database.ValidationError.NotFound:
                ProcessDebugMessage(string.Format("Entity {0} at {1} not found!", message.Entity, ip));
                ServerCommand sv_cmd_entity_not_found = new ServerCommand
                {
                    Command = ServerOperations.EntityNoLongerAvailable.Value
                };
                server.SendMessage(sv_cmd_entity_not_found,
                                   PacketType.ServerCommand,
                                   database.RetreiveEntityKey(clientHandler.Entity),
                                   clientHandler.Socket);
                break;

            case Database.ValidationError.InvalidTime:
                ProcessDebugMessage("Packet time missmatch");
                ServerCommand sv_cmd_ts_missmatch = new ServerCommand
                {
                    Command = ServerOperations.InvalidTime.Value
                };
                server.SendMessage(sv_cmd_ts_missmatch,
                                   PacketType.ClientMessage,
                                   database.RetreiveEntityKey(clientHandler.Entity),
                                   clientHandler.Socket);
                break;
            }

            if (enableDebug)
            {
                Console.WriteLine("");
                Console.Write("\r" + menuManager.commandPrefix);
            }
        }