예제 #1
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));
        }
예제 #2
0
        public Task <bool> OnHandle(MessageContext context, EncryptedReliableMessage message)
        {
            Crypt crypt;
            // TODO Decrypt P2P
            //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
            {
                crypt = context.Session.Crypt;
            }

            var buffer = context.ChannelHandlerContext.Allocator.Buffer(message.Data.Length);

            using (var src = new MemoryStream(message.Data))
                using (var dst = new WriteOnlyByteBufferStream(buffer, false))
                    crypt.Decrypt(context.ChannelHandlerContext.Allocator, message.EncryptMode, src, dst, true);

            context.Message = buffer;
            context.ChannelHandlerContext.Channel.Pipeline.Context <MessageContextDecoder>().FireChannelRead(context);
            return(Task.FromResult(true));
        }
예제 #3
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();
            }
        }
예제 #4
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();
            }
        }
예제 #5
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();
            }
        }
예제 #6
0
        public void EncryptedReliableMessage(IChannelHandlerContext context, ProudSession session, EncryptedReliableMessage message, RecvContext recvContext)
        {
            var crypt = session.Crypt;

            if (crypt == null)
            {
                return;
            }

            var buffer = context.Allocator.Buffer(message.Data.Length);

            using (var src = new MemoryStream(message.Data))
                using (var dst = new WriteOnlyByteBufferStream(buffer, false))
                {
                    crypt.Decrypt(context.Allocator, message.EncryptMode, src, dst, true);
                }

            recvContext.Message = buffer;
            context.Channel.Pipeline.Context <ProudFrameDecoder>().FireChannelRead(recvContext);
        }
        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);
            }
        }