예제 #1
0
        public void CompressedMessage(IService service, CompressedMessage message, MessageReceivedEventArgs e)
        {
            var decompressed = message.Data.DecompressZLib();

            ProudCoreOpCode opCode;

            byte[] data;
            using (var r = decompressed.ToBinaryReader())
            {
                opCode = r.ReadEnum <ProudCoreOpCode>();
                data   = r.ReadToEnd();
            }
            switch (opCode)
            {
            case ProudCoreOpCode.Rmi:
                var rmi = new RmiMessage(data)
                {
                    IsRelayed    = message.IsRelayed,
                    SenderHostId = message.SenderHostId,
                    TargetHostId = message.TargetHostId
                };
                e.Message = rmi;
                _filter.OnMessageReceived(e);
                break;

            default:
                throw new ProudException("Invalid opCode inside CompressedMessage: " + opCode);
            }
        }
예제 #2
0
        public void RmiMessage(ProudSession session, RmiMessage message, MessageReceivedEventArgs e)
        {
            var rmiId = BitConverter.ToUInt16(message.Data, 0);

            if (rmiId >= 60000)
            {
                using (var r = message.Data.ToBinaryReader())
                {
                    var opCode       = r.ReadEnum <ProudOpCode>();
                    var proudMessage = ProudMapper.GetMessage(opCode, r);

                    if (!r.IsEOF())
#if DEBUG
                    {
                        r.BaseStream.Position = 0;
                        throw new ProudBadFormatException(proudMessage.GetType(), r.ReadToEnd());
                    }
#else
                    { throw new ProudBadFormatException(proudMessage.GetType()); }
#endif
                    e.Message = proudMessage;
                    OnProudMessageReceived(e);
                }
                return;
            }

            e.Message = new ProudRmiMessage(message.Data);
            _filter.NextOnMessageReceived(e);
        }
예제 #3
0
        internal Task ProcessAndSendMessage(MessageEventArgs e, EncryptContext context)
        {
            var         message     = (ProudMessage)e.Message;
            var         data        = message.ToArray();
            CoreMessage coreMessage = new RmiMessage(data);

            if (message.Compress)
            {
                data        = coreMessage.ToArray();
                coreMessage = new CompressedMessage(data.Length, data.CompressZLib());
            }

            if (message.Encrypt)
            {
                data = coreMessage.ToArray();
                using (var w = new PooledMemoryStream(Service.ArrayPool).ToBinaryWriter(false))
                {
                    w.Write(context.EncryptCounter);
                    w.Write(data);

                    data = w.ToArray();
                }

                data        = context.Encrypt(data);
                coreMessage = new EncryptedReliableMessage(data);
            }

            e.Message = coreMessage;
            return(base.OnSendMessage(e));
        }
예제 #4
0
        public void RmiMessage(IChannelHandlerContext context, RmiMessage message, RecvContext recvContext)
        {
            var buffer = Unpooled.WrappedBuffer(message.Data);

            recvContext.Message = buffer;
            context.FireChannelRead(recvContext);
        }
    public override void ChannelActive(IChannelHandlerContext context)
    {
        base.ChannelActive(context);
        RmiMessage firstMessage = new RmiMessage();

        firstMessage.Write(MessageType.Notify);
        firstMessage.Write("<region>EU-S4L</region>");
        SendA(context, firstMessage);
    }
        public void UnreliableRelayHandler(ProudSession session, UnreliableRelay1Message message, MessageReceivedEventArgs e)
        {
            foreach (var destination in message.Destination.Where(id => id != session.HostId))
            {
                if (session.P2PGroup == null)
                {
                    Logger.Debug()
                    .Message("Client {0} in not a p2pgroup", session.HostId)
                    .Write();
                    return;
                }

                if (!session.P2PGroup.Members.ContainsKey(destination))
                {
                    Logger.Debug()
                    .Message("Client {0} trying to relay to non existant {1}", session.HostId, destination)
                    .Write();
                    return;
                }

                if (destination == 2)
                {
                    #region Hardcoded ServerMember

                    ProudCoreOpCode opCode;
                    byte[]          data;
                    using (var r = message.Data.ToBinaryReader())
                    {
                        opCode = r.ReadEnum <ProudCoreOpCode>();
                        data   = r.ReadToEnd();
                    }

                    if (opCode == ProudCoreOpCode.Rmi)
                    {
                        var core = new RmiMessage(data)
                        {
                            IsRelayed    = true,
                            SenderHostId = session.HostId,
                            TargetHostId = destination
                        };
                        e.Message = core;
                        _filter.OnMessageReceived(e);
                    }
                    else
                    {
                        throw new ProudException($"Invalid opCode {opCode}");
                    }

                    #endregion
                }
                else
                {
                    var target = _filter.SessionLookupByHostId.GetValueOrDefault(destination);
                    target?.Send(new UnreliableRelay2Message(session.HostId, message.Data));
                }
            }
        }
    public void RmiSend(IChannelHandlerContext ctx, short RmiID, RmiMessage message)
    {
        RmiMessage rmiframe = new RmiMessage();

        rmiframe.Write(MessageType.Rmi);
        rmiframe.Write(RmiID);
        rmiframe.Write(message);
        SendA(ctx, rmiframe);
    }
예제 #8
0
        protected override void Encode(IChannelHandlerContext context, SendContext message, List <object> output)
        {
            var buffer = message.Message as IByteBuffer;

            if (buffer == null)
            {
                throw new ProudException($"{nameof(SendContextEncoder)} can only handle {nameof(IByteBuffer)}");
            }

            try
            {
                var          data        = buffer.ToArray();
                ICoreMessage coreMessage = new RmiMessage(data);
                var          session     = context.Channel.GetAttribute(ChannelAttributes.Session).Get();
                if (session == null)
                {
                    return;
                }

                var server = context.Channel.GetAttribute(ChannelAttributes.Server).Get();

                if (data.Length > server.Configuration.MessageMaxLength)
                {
                    throw new ProudException("Message is longer than max messagelength!");
                }
                //else if (data.Length > server.Configuration.MaxUncompressedMessageLength &&
                //    coreMessage.GetType() != typeof(CompressedMessage))
                //    message.SendOptions.Compress = true;

                if (message.SendOptions.Compress)
                {
                    data        = CoreMessageEncoder.Encode(coreMessage);
                    coreMessage = new CompressedMessage(data.Length, data.CompressZLib());
                }

                if (message.SendOptions.Encrypt)
                {
                    data = CoreMessageEncoder.Encode(coreMessage);
                    using (var src = new MemoryStream(data))
                        using (var dst = new MemoryStream())
                        {
                            session.Crypt?.Encrypt(context.Allocator, EncryptMode.Secure, src, dst, true);
                            data = dst.ToArray();
                        }
                    coreMessage = new EncryptedReliableMessage(data, EncryptMode.Secure);
                }

                output.Add(coreMessage);
            }
            finally
            {
                buffer.Release();
            }
        }
예제 #9
0
        public void RmiMessage(IChannelHandlerContext context, RmiMessage message)
        {
            var buffer = Unpooled.WrappedBuffer(message.Data);

            try
            {
                context.FireChannelRead(buffer);
            }
            catch (Exception e) // TODO: What is this try/catch?
            {
            }
        }
    public void SendA(IChannelHandlerContext ctx, RmiMessage data)
    {
        RmiMessage coreframe = new RmiMessage();

        coreframe.Write(Magic);
        coreframe.WriteScalar(data.Length);
        coreframe.Write(data);

        IByteBuffer buffer = Unpooled.Buffer(coreframe.Length);

        buffer.WriteBytes(coreframe.Buffer);
        ctx.WriteAndFlushAsync(buffer);
    }
예제 #11
0
        protected override void Encode(IChannelHandlerContext context, SendContext message, List <object> output)
        {
            if (!(message.Message is IByteBuffer buffer))
            {
                throw new ProudException($"{nameof(SendContextEncoder)} can only handle {nameof(IByteBuffer)}");
            }

            try
            {
                var          data        = buffer.GetIoBuffer().ToArray();
                ICoreMessage coreMessage = new RmiMessage(data);

                if (message.SendOptions.RelayFrom > 0)
                {
                    data        = CoreMessageEncoder.Encode(_serializer, coreMessage);
                    coreMessage = new UnreliableRelay2Message(message.SendOptions.RelayFrom, data);
                }
                else
                {
                    if (message.SendOptions.Compress)
                    {
                        data        = CoreMessageEncoder.Encode(_serializer, coreMessage);
                        coreMessage = new CompressedMessage(data.Length, data.CompressZLib());
                    }

                    if (message.SendOptions.Encrypt)
                    {
                        data = CoreMessageEncoder.Encode(_serializer, coreMessage);
                        var session = context.Channel.GetAttribute(ChannelAttributes.Session).Get();
                        using (var src = new MemoryStream(data))
                            using (var dst = new MemoryStream())
                            {
                                session.Crypt.Encrypt(context.Allocator, EncryptMode.Secure, src, dst, true);
                                data = dst.ToArray();
                            }

                        coreMessage = new EncryptedReliableMessage(data, EncryptMode.Secure);
                    }
                }

                output.Add(coreMessage);
            }
            finally
            {
                buffer.Release();
            }
        }
예제 #12
0
        protected override void Encode(IChannelHandlerContext context, SendContext message, List <object> output)
        {
            var buffer = message.Message as IByteBuffer;

            if (buffer == null)
            {
                throw new ProudException($"{nameof(SendContextEncoder)} can only handle {nameof(IByteBuffer)}");
            }

            try
            {
                var          data        = buffer.ToArray();
                ICoreMessage coreMessage = new RmiMessage(data);

                if (message.SendOptions.Compress)
                {
                    data        = CoreMessageEncoder.Encode(coreMessage);
                    coreMessage = new CompressedMessage(data.Length, data.CompressZLib());
                }

                if (message.SendOptions.Encrypt)
                {
                    data = CoreMessageEncoder.Encode(coreMessage);
                    var session = context.Channel.GetAttribute(ChannelAttributes.Session).Get();
                    using (var src = new MemoryStream(data))
                        using (var dst = new MemoryStream())
                        {
                            session.Crypt.Encrypt(src, dst, true);
                            data = dst.ToArray();
                        }
                    coreMessage = new EncryptedReliableMessage(data);
                }

                output.Add(coreMessage);
            }
            finally
            {
                buffer.Release();
            }
        }
        public void EncryptedReliableMessage(ProudSession session, EncryptedReliableMessage message, MessageReceivedEventArgs e)
        {
            EncryptContext encryptContext;

            if (message.IsRelayed)
            {
                var remotePeer = (ServerRemotePeer)session.P2PGroup?.Members.GetValueOrDefault(message.TargetHostId);
                if (remotePeer == null)
                {
                    return;
                }

                encryptContext = remotePeer.EncryptContext;
                if (encryptContext == null)
                {
                    throw new ProudException($"Received encrypted message but the remote peer has no encryption enabled");
                }
            }
            else
            {
                encryptContext = session.EncryptContext;
            }

            var decrypted = encryptContext.Decrypt(message.Data);

            ushort decryptCounter;

            byte[] data;
            using (var r = decrypted.ToBinaryReader())
            {
                decryptCounter = r.ReadUInt16();
                data           = r.ReadToEnd();
            }

            if (decryptCounter != (session.EncryptContext.DecryptCounter - 1))
            {
                throw new ProudException($"Invalid DecryptCounter! Message: {decryptCounter} Client: {session.EncryptContext.DecryptCounter}");
            }

            ProudCoreOpCode opCode;

            using (var r = data.ToBinaryReader())
            {
                opCode = r.ReadEnum <ProudCoreOpCode>();
                data   = r.ReadToEnd();
            }

            switch (opCode)
            {
            case ProudCoreOpCode.Rmi:
                var rmi = new RmiMessage(data)
                {
                    IsRelayed    = message.IsRelayed,
                    SenderHostId = message.SenderHostId,
                    TargetHostId = message.TargetHostId
                };
                e.Message = rmi;
                _filter.OnMessageReceived(e);
                break;

            case ProudCoreOpCode.Compressed:
                CompressedMessage compressed;
                using (var r = data.ToBinaryReader())
                    compressed = Serializer.Deserialize <CompressedMessage>(r);
                compressed.IsRelayed    = message.IsRelayed;
                compressed.SenderHostId = message.SenderHostId;
                compressed.TargetHostId = message.TargetHostId;
                e.Message = compressed;
                _filter.OnMessageReceived(e);
                break;

            default:
                throw new ProudException("Invalid opCode inside EncryptedMessage: " + opCode);
            }
        }
        public void ReliableRelayHandler(ProudSession session, ReliableRelay1Message message, MessageReceivedEventArgs e)
        {
            if (session.P2PGroup == null)
            {
                return;
            }

            foreach (var destination in message.Destination.Where(d => d.HostId != session.HostId))
            {
                if (session.P2PGroup == null)
                {
                    Logger.Debug($"Client {session.HostId} is not in a P2PGroup");
                    return;
                }

                if (!session.P2PGroup.Members.ContainsKey(destination.HostId))
                {
                    Logger.Debug($"Client {session.HostId} trying to relay to non existant {destination.HostId}");
                    return;
                }

                if (destination.HostId == 2)
                {
                    #region Hardcoded ServerMember

                    ProudCoreOpCode opCode;
                    byte[]          data;
                    using (var r = message.Data.ToBinaryReader())
                    {
                        opCode = r.ReadEnum <ProudCoreOpCode>();
                        data   = r.ReadToEnd();
                    }

                    if (opCode == ProudCoreOpCode.Rmi)
                    {
                        var core = new RmiMessage(data)
                        {
                            IsRelayed    = true,
                            SenderHostId = session.HostId,
                            TargetHostId = destination.HostId
                        };
                        e.Message = core;
                        _filter.OnMessageReceived(e);
                    }
                    else if (opCode == ProudCoreOpCode.ReliableUdp_Frame)
                    {
                        ReliableUdp_FrameMessage udpFrameMessage;
                        using (var r = data.ToBinaryReader())
                            udpFrameMessage = Serializer.Deserialize <ReliableUdp_FrameMessage>(r);

                        using (var r = udpFrameMessage.Data.ToBinaryReader())
                        {
                            opCode = r.ReadEnum <ProudCoreOpCode>();
                            data   = r.ReadToEnd();
                        }

                        CoreMessage core;
                        if (opCode == ProudCoreOpCode.Rmi)
                        {
                            core = new RmiMessage(data)
                            {
                                IsRelayed    = true,
                                SenderHostId = session.HostId,
                                TargetHostId = destination.HostId
                            };
                        }
                        else if (opCode == ProudCoreOpCode.EncryptedReliable)
                        {
                            using (var r = data.ToBinaryReader())
                                core = Serializer.Deserialize <EncryptedReliableMessage>(r);
                            core.IsRelayed    = true;
                            core.SenderHostId = session.HostId;
                            core.TargetHostId = destination.HostId;
                        }
                        else
                        {
                            throw new ProudException($"Invalid opCode {opCode}");
                        }

                        e.Message = core;
                        _filter.OnMessageReceived(e);
                    }
                    else
                    {
                        throw new ProudException($"Invalid opCode {opCode}");
                    }

                    #endregion
                }
                else
                {
                    var target = _filter.SessionLookupByHostId.GetValueOrDefault(destination.HostId);
                    target?.Send(new ReliableRelay2Message(new RelayDestinationDto(session.HostId, destination.FrameNumber), message.Data));
                }
            }
        }
예제 #15
0
        public void RmiMessage(IChannelHandlerContext context, RmiMessage message)
        {
            var buffer = Unpooled.WrappedBuffer(message.Data);

            context.FireChannelRead(buffer);
        }
예제 #16
0
 internal void Write(RmiMessage obj)
 {
     Write(obj._buffer);
 }
    public override void ChannelRead(IChannelHandlerContext context, object messageData)
    {
        var buffer = messageData as IByteBuffer;

        byte[] data = buffer.ToArray();

        RmiMessage __msg    = new RmiMessage(data, data.Length);
        short      magic    = 0;
        ByteArray  _message = new ByteArray();

        if (__msg.Read(ref magic) &&
            magic == Magic &&
            __msg.Read(ref _message))
        {
            RmiMessage  message = new RmiMessage(_message);
            MessageType coreID  = 0;
            if (message.Read(ref coreID))
            {
                switch (coreID)
                {
                case MessageType.Rmi:
                {
                    short RmiID = 0;
                    if (message.Read(ref RmiID))
                    {
                        switch (RmiID)
                        {
                        case 15:
                        {
                            AccountDto account;
                            string     Username = "";
                            string     Password = "";
                            bool       register = false;

                            if (message.Read(ref Username) &&
                                message.Read(ref Password) &&
                                message.Read(ref register))
                            {
                                using (var db = AuthDatabase.Open())
                                {
                                    Logger.Information("Authentication login from {endpoint}", context.Channel.RemoteAddress.ToString());

                                    if (Username.Length > 5 && Password.Length > 5)
                                    {
                                        var result = db.Find <AccountDto>(statement => statement
                                                                          .Where($"{nameof(AccountDto.Username):C} = @{nameof(Username)}")
                                                                          .Include <BanDto>(join => join.LeftOuterJoin())
                                                                          .WithParameters(new { Username }));

                                        account = result.FirstOrDefault();

                                        if (account == null)
                                        {
                                            account = new AccountDto {
                                                Username = Username
                                            };

                                            var newSalt = new byte[24];
                                            using (var csprng = new RNGCryptoServiceProvider())
                                                csprng.GetBytes(newSalt);

                                            var hash = new byte[24];
                                            using (var pbkdf2 = new Rfc2898DeriveBytes(Password, newSalt, 24000))
                                                hash = pbkdf2.GetBytes(24);

                                            account.Password = Convert.ToBase64String(hash);

                                            account.Salt = Convert.ToBase64String(newSalt);

                                            db.InsertAsync(account);
                                        }

                                        var salt = Convert.FromBase64String(account.Salt);

                                        var passwordGuess = new byte[24];
                                        using (var pbkdf2 = new Rfc2898DeriveBytes(Password, salt, 24000))
                                            passwordGuess = pbkdf2.GetBytes(24);

                                        var actualPassword = Convert.FromBase64String(account.Password);

                                        uint difference = (uint)passwordGuess.Length ^ (uint)actualPassword.Length;

                                        for (var i = 0; i < passwordGuess.Length && i < actualPassword.Length; i++)
                                        {
                                            difference |= (uint)(passwordGuess[i] ^ actualPassword[i]);
                                        }

                                        if (difference != 0 || string.IsNullOrWhiteSpace(account.Password))
                                        {
                                            Logger.Error("Wrong authentication credentials for {username} / {endpoint}", Username, context.Channel.RemoteAddress.ToString());
                                            RmiMessage ack = new RmiMessage();
                                            ack.Write(false);
                                            ack.Write("Login failed");
                                            RmiSend(context, 16, ack);
                                        }
                                        else
                                        {
                                            account.LoginToken = AuthHash.GetHash256($"{context.Channel.RemoteAddress.ToString()}-{account.Username}-{account.Password}").ToLower();
                                            account.LastLogin  = $"{DateTimeOffset.Now}";
                                            account.AuthToken  = "";
                                            account.newToken   = "";
                                            db.UpdateAsync(account);

                                            RmiMessage ack = new RmiMessage();
                                            ack.Write(true);
                                            ack.Write(account.LoginToken);
                                            RmiSend(context, 16, ack);
                                            Logger.Information("Authentication success for {username}", Username);
                                        }
                                    }
                                    else
                                    {
                                        Logger.Error("Wrong authentication credentials for {username} / {endpoint}", Username, context.Channel.RemoteAddress.ToString());
                                        RmiMessage ack = new RmiMessage();
                                        ack.Write(false);
                                        ack.Write("Invalid length of username/password");
                                        RmiSend(context, 16, ack);
                                    }
                                }
                            }
                            else
                            {
                                Logger.Error("Wrong login for {endpoint}", context.Channel.RemoteAddress.ToString());
                                RmiMessage ack = new RmiMessage();
                                ack.Write(false);
                                ack.Write("Invalid loginpacket");
                                RmiSend(context, 16, ack);
                            }
                            break;
                        }

                        case 17:
                            context.CloseAsync();
                            break;

                        default:
                            Logger.Error("Received unknown rmiID{rmi} from {endpoint}", RmiID, context.Channel.RemoteAddress.ToString());
                            break;
                        }
                    }
                    break;
                }

                case MessageType.Notify:
                {
                    string info = "";
                    message.Read(ref info);
                    Logger.Information("Received info! -> {received}", info);
                    break;
                }

                default:
                    Logger.Error("Received unknown coreID{coreid} from {endpoint}", coreID, context.Channel.RemoteAddress.ToString());
                    break;
                }
            }
        }
        else
        {
            Logger.Error("Received invalid packetstruct from {endpoint}", context.Channel.RemoteAddress.ToString());
            context.CloseAsync();
        }
    }