Example #1
0
        public void TestAnnotations()
        {
            var annotations = new Dictionary<string,byte[]>();
            annotations["TEST"]=new byte[]{10,20,30,40,50};

            var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, annotations);
            byte[] data = msg.to_bytes();
            int annotations_size = 4+2+20 + 4+2+5;
            Assert.AreEqual(Message.HEADER_SIZE + 5 + annotations_size, data.Length);
            Assert.AreEqual(annotations_size, msg.annotations_size);
            Assert.AreEqual(2, msg.annotations.Count);
            Assert.AreEqual(new byte[]{10,20,30,40,50}, msg.annotations["TEST"]);
            byte[] mac = pyrohmac(new byte[]{1,2,3,4,5}, annotations);
            Assert.AreEqual(mac, msg.annotations["HMAC"]);
        }
Example #2
0
	public void TestMessage()
	{
		new Message(99, new byte[0], this.serializer_id, 0, 0, null);  // doesn't check msg type here
		Assert.Throws(typeof(PyroException), ()=>Message.from_header(Encoding.ASCII.GetBytes("FOOBAR")));
		var msg = new Message(Message.MSG_CONNECT, Encoding.ASCII.GetBytes("hello"), this.serializer_id, 0, 0, null);
		Assert.AreEqual(Message.MSG_CONNECT, msg.type);
		Assert.AreEqual(5, msg.data_size);
		Assert.AreEqual(new byte[]{(byte)'h',(byte)'e',(byte)'l',(byte)'l',(byte)'o'}, msg.data);
		Assert.AreEqual(4+2+20, msg.annotations_size);
		byte[] mac = pyrohmac(Encoding.ASCII.GetBytes("hello"), msg.annotations);
		var expected = new Dictionary<string, byte[]>();
		expected["HMAC"] = mac;
		CollectionAssert.AreEqual(expected, msg.annotations);

		byte[] hdr = msg.to_bytes().Take(Message.HEADER_SIZE).ToArray();
		msg = Message.from_header(hdr);
		Assert.AreEqual(Message.MSG_CONNECT, msg.type);
		Assert.AreEqual(4+2+20, msg.annotations_size);
		Assert.AreEqual(5, msg.data_size);

		hdr = new Message(Message.MSG_RESULT, new byte[0], this.serializer_id, 0, 0, null).to_bytes().Take(Message.HEADER_SIZE).ToArray();
		msg = Message.from_header(hdr);
		Assert.AreEqual(Message.MSG_RESULT, msg.type);
		Assert.AreEqual(4+2+20, msg.annotations_size);
		Assert.AreEqual(0, msg.data_size);

		hdr = new Message(Message.MSG_RESULT, Encoding.ASCII.GetBytes("hello"), 12345, 60006, 30003, null).to_bytes().Take(Message.HEADER_SIZE).ToArray();
		msg = Message.from_header(hdr);
		Assert.AreEqual(Message.MSG_RESULT, msg.type);
		Assert.AreEqual(60006, msg.flags);
		Assert.AreEqual(5, msg.data_size);
		Assert.AreEqual(12345, msg.serializer_id);
		Assert.AreEqual(30003, msg.seq);

		byte[] data = new Message(255, new byte[0], this.serializer_id, 0, 255, null).to_bytes();
		Assert.AreEqual(50, data.Length);
		data = new Message(1, new byte[0], this.serializer_id, 0, 255, null).to_bytes();
		Assert.AreEqual(50, data.Length);
		data = new Message(1, new byte[0], this.serializer_id, 253, 254, null).to_bytes();
		Assert.AreEqual(50, data.Length);

		// compression is a job of the code supplying the data, so the messagefactory should leave it untouched
		data = new byte[1000];
		byte[] msg_bytes1 = new Message(Message.MSG_INVOKE, data, this.serializer_id, 0, 0, null).to_bytes();
		byte[] msg_bytes2 = new Message(Message.MSG_INVOKE, data, this.serializer_id, Message.FLAGS_COMPRESSED, 0, null).to_bytes();
		Assert.AreEqual(msg_bytes1.Length, msg_bytes2.Length);
	}
Example #3
0
 public void testAnnotationsIdLength4()
 {
     try {
     var anno = new Dictionary<string, byte[]>();
     anno["TOOLONG"] = new byte[]{10,20,30};
     var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, anno);
     byte[]data = msg.to_bytes();
     Assert.Fail("should fail, too long");
     } catch(ArgumentException) {
     //ok
     }
     try {
     var anno = new Dictionary<string, byte[]>();
     anno["QQ"] = new byte[]{10,20,30};
     var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, anno);
     byte[] data = msg.to_bytes();
     Assert.Fail("should fail, too short");
     } catch (ArgumentException) {
     //ok
     }
 }
Example #4
0
        public void TestAnnotations()
        {
            byte[] hmac=Encoding.UTF8.GetBytes("secret");

            var annotations = new Dictionary<string,byte[]>();
            annotations["TES1"]=new byte[]{10,20,30,40,50};
            annotations["TES2"]=new byte[]{20,30,40,50,60};
            annotations["TES3"]=new byte[]{30,40,50,60,70};
            annotations["TES4"]=new byte[]{40,50,60,70,80};

            var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, annotations, hmac);
            byte[] data = msg.to_bytes();
            int annotations_size = 4+2+20 + (4+2+5)*4;
            Assert.AreEqual(Message.HEADER_SIZE + 5 + annotations_size, data.Length);
            Assert.AreEqual(annotations_size, msg.annotations_size);
            Assert.AreEqual(5, msg.annotations.Count);
            Assert.AreEqual(new byte[]{10,20,30,40,50}, msg.annotations["TES1"]);
            Assert.AreEqual(new byte[]{20,30,40,50,60}, msg.annotations["TES2"]);
            Assert.AreEqual(new byte[]{30,40,50,60,70}, msg.annotations["TES3"]);
            Assert.AreEqual(new byte[]{40,50,60,70,80}, msg.annotations["TES4"]);
            byte[] mac = msg.hmac(hmac);
            Assert.AreEqual(mac, msg.annotations["HMAC"]);

            annotations = new Dictionary<string,byte[]>();
            annotations["TES4"]=new byte[]{40,50,60,70,80};
            annotations["TES3"]=new byte[]{30,40,50,60,70};
            annotations["TES2"]=new byte[]{20,30,40,50,60};
            annotations["TES1"]=new byte[]{10,20,30,40,50};
            var msg2 = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, annotations, hmac);
            Assert.AreEqual(msg.hmac(hmac), msg2.hmac(hmac));

            annotations = new Dictionary<string,byte[]>();
            annotations["TES4"]=new byte[]{40,50,60,70,80};
            var msg3 = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, annotations, hmac);
            Assert.AreNotEqual(msg.hmac(hmac), msg3.hmac(hmac));
        }
Example #5
0
 public void testRecvNoAnnotations()
 {
     var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, 42, 0, 0, null);
     var c = new ConnectionMock();
     c.send(msg.to_bytes());
     msg = Message.recv(c, null);
     Assert.AreEqual(0, c.RemainingLength);
     Assert.AreEqual(5, msg.data_size);
     Assert.AreEqual(new byte[]{1,2,3,4,5}, msg.data);
     Assert.AreEqual(0, msg.annotations_size);
     Assert.AreEqual(0, msg.annotations.Count);
 }
Example #6
0
 public void testRecvAnnotations()
 {
     var annotations = new Dictionary<string, byte[]>();
     annotations["TEST"] = new byte[]{10, 20,30,40,50};
     var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, annotations);
     var c = new ConnectionMock();
     c.send(msg.to_bytes());
     msg = Message.recv(c, null);
     Assert.AreEqual(0, c.RemainingLength);
     Assert.AreEqual(5, msg.data_size);
     Assert.AreEqual(new byte[]{1,2,3,4,5}, msg.data);
     Assert.AreEqual(new byte[]{10,20,30,40,50}, msg.annotations["TEST"]);
     Assert.IsTrue(msg.annotations.ContainsKey("HMAC"));
 }
Example #7
0
 public void testProtocolVersion()
 {
     byte[] msg = new Message(Message.MSG_RESULT, new byte[0], this.serializer_id, 0, 1, null).to_bytes().Take(Message.HEADER_SIZE).ToArray();
     msg[4] = 99; // screw up protocol version in message header
     Message.from_header(msg);
 }
Example #8
0
        public void testRecvAnnotations()
        {
            var annotations = new Dictionary<string, byte[]>();
            annotations["TEST"] = new byte[]{10, 20,30,40,50};
            var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, this.serializer_id, 0, 0, annotations, Encoding.UTF8.GetBytes("secret"));

            var ms = new MemoryStream(msg.to_bytes());
            msg = Message.recv(ms, null, Encoding.UTF8.GetBytes("secret"));
            Assert.AreEqual(-1, ms.ReadByte());
            Assert.AreEqual(5, msg.data_size);
            Assert.AreEqual(new byte[]{1,2,3,4,5}, msg.data);
            Assert.AreEqual(new byte[]{10,20,30,40,50}, msg.annotations["TEST"]);
            Assert.IsTrue(msg.annotations.ContainsKey("HMAC"));
        }
Example #9
0
 /// <summary>
 /// Decompress the data bytes in the given message (in place).
 /// </summary>
 private void _decompressMessageData(Message msg)
 {
     if((msg.flags & Message.FLAGS_COMPRESSED) == 0) {
     throw new ArgumentException("message data is not compressed");
     }
     using(MemoryStream compressed=new MemoryStream(msg.data, 2, msg.data.Length-2, false)) {
     using(DeflateStream decompresser=new DeflateStream(compressed, CompressionMode.Decompress)) {
         MemoryStream bos = new MemoryStream(msg.data.Length);
         byte[] buffer = new byte[4096];
         int numRead;
         while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0) {
             bos.Write(buffer, 0, numRead);
         }
         msg.data=bos.ToArray();
         msg.flags ^= Message.FLAGS_COMPRESSED;
     }
     }
 }
Example #10
0
        /// <summary>
        /// Perform the Pyro protocol connection handshake with the Pyro daemon.
        /// </summary>
        protected void _handshake()
        {
            var ser = PyroSerializer.GetFor(Config.SERIALIZER);
            var handshakedata = new Dictionary<string, Object>();
            handshakedata["handshake"] = pyroHandshake;
            if(Config.METADATA)
            handshakedata["object"] = objectid;
            byte[] data = ser.serializeData(handshakedata);
            ushort flags = Config.METADATA? Message.FLAGS_META_ON_CONNECT : (ushort)0;
            var msg = new Message(Message.MSG_CONNECT, data, ser.serializer_id, flags, sequenceNr, annotations(), pyroHmacKey);
            IOUtil.send(sock_stream, msg.to_bytes());
            if(Config.MSG_TRACE_DIR!=null) {
            Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }

            // process handshake response
            msg = Message.recv(sock_stream, new ushort[]{Message.MSG_CONNECTOK, Message.MSG_CONNECTFAIL}, pyroHmacKey);
            responseAnnotations(msg.annotations, msg.type);
            object handshake_response = "?";
            if(msg.data!=null) {
            if((msg.flags & Message.FLAGS_COMPRESSED) != 0) {
                _decompressMessageData(msg);
            }
            handshake_response = ser.deserializeData(msg.data);
            }
            if(msg.type==Message.MSG_CONNECTOK) {
            if((msg.flags & Message.FLAGS_META_ON_CONNECT) != 0) {
                var response_dict = (Hashtable)handshake_response;
                _processMetadata(response_dict["meta"] as Hashtable);
                handshake_response = response_dict["handshake"];
                try {
                    validateHandshake(handshake_response);
                } catch (Exception) {
                    close();
                    throw;
                }
            }
            } else if (msg.type==Message.MSG_CONNECTFAIL) {
            close();
            throw new PyroException("connection rejected, reason: "+handshake_response);
            } else {
            close();
            throw new PyroException(string.Format("connect: invalid msg type {0} received", msg.type));
            }
        }
Example #11
0
	public void testProtocolVersionsNotSupported2()
	{
		byte[] msg = new Message(Message.MSG_RESULT, new byte[0], this.serializer_id, 0, 1, null).to_bytes().Take(Message.HEADER_SIZE).ToArray();
		msg[4] = 0;
		msg[5] = 48;	
		Message.from_header(msg);
	}
Example #12
0
        /**
         * Internal call method to actually perform the Pyro method call and process the result.
         */
        private object call(string method, ushort flags, params object[] parameters)
        {
            lock(this) {
            connect();
            unchecked {
                sequenceNr++;        // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
            }
            }
            if (parameters == null)
            parameters = new object[] {};
            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);
            byte[] pickle = ser.serializeCall(objectid, method, parameters, new Dictionary<string,object>(0));
            var msg = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, null);
            Message resultmsg;
            lock (this.sock) {
            IOUtil.send(sock_stream, msg.to_bytes());
            if(Config.MSG_TRACE_DIR!=null) {
                Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }
            pickle = null;

            if ((flags & Message.FLAGS_ONEWAY) != 0)
                return null;

            resultmsg = Message.recv(sock_stream, new ushort[]{Message.MSG_RESULT});
            }
            if (resultmsg.seq != sequenceNr) {
            throw new PyroException("result msg out of sync");
            }
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0) {
            // we need to skip the first 2 bytes in the buffer due to a tiny mismatch between zlib-written
            // data and the deflate data bytes that .net expects.
            // See http://www.chiramattel.com/george/blog/2007/09/09/deflatestream-block-length-does-not-match.html
            using(MemoryStream compressed=new MemoryStream(resultmsg.data, 2, resultmsg.data.Length-2, false)) {
                using(DeflateStream decompresser=new DeflateStream(compressed, CompressionMode.Decompress)) {
                    MemoryStream bos = new MemoryStream(resultmsg.data.Length);
                    byte[] buffer = new byte[4096];
                    int numRead;
                    while ((numRead = decompresser.Read(buffer, 0, buffer.Length)) != 0) {
                        bos.Write(buffer, 0, numRead);
                    }
                    resultmsg.data=bos.ToArray();
                }
            }
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0) {
            Exception rx = (Exception) ser.deserializeData(resultmsg.data);
            if (rx is PyroException) {
                throw (PyroException) rx;
            } else {
                PyroException px = new PyroException("remote exception occurred", rx);
                PropertyInfo remotetbProperty=rx.GetType().GetProperty("_pyroTraceback");
                if(remotetbProperty!=null) {
                    string remotetb=(string)remotetbProperty.GetValue(rx,null);
                    px._pyroTraceback=remotetb;
                }
                throw px;
            }
            }

            return ser.deserializeData(resultmsg.data);
        }
Example #13
0
 public void testChecksum()
 {
     var msg = new Message(Message.MSG_RESULT, new byte[]{1,2,3,4}, 42, 0, 1, null, null);
     byte[] data = msg.to_bytes();
     // corrupt the checksum bytes
     data[Message.HEADER_SIZE-2] = 0;
     data[Message.HEADER_SIZE-1] = 0;
     Stream ms = new MemoryStream(data);
     try {
     Message.recv(ms, null, null);
     Assert.Fail("crash expected");
     }
     catch(PyroException x) {
     Assert.IsTrue(x.Message.Contains("checksum"));
     }
 }
Example #14
0
 public void testRecvNoAnnotations()
 {
     var msg = new Message(Message.MSG_CONNECT, new byte[]{1,2,3,4,5}, 42, 0, 0, null, null);
     byte[] data = msg.to_bytes();
     var ms = new MemoryStream(data);
     msg = Message.recv(ms, null, null);
     Assert.AreEqual(-1, ms.ReadByte());
     Assert.AreEqual(5, msg.data_size);
     Assert.AreEqual(new byte[]{1,2,3,4,5}, msg.data);
     Assert.AreEqual(0, msg.annotations_size);
     Assert.AreEqual(0, msg.annotations.Count);
 }
Example #15
0
 public void testChecksum()
 {
     var msg = new Message(Message.MSG_RESULT, new byte[]{1,2,3,4}, 42, 0, 1, null);
     var c = new ConnectionMock();
     c.send(msg.to_bytes());
     // corrupt the checksum bytes
     byte[] data = c.ReceivedData;
     data[Message.HEADER_SIZE-2] = 0;
     data[Message.HEADER_SIZE-1] = 0;
     c = new ConnectionMock(data);
     try {
     Message.recv(c, null);
     Assert.Fail("crash expected");
     }
     catch(PyroException x) {
     Assert.IsTrue(x.Message.Contains("checksum"));
     }
 }
Example #16
0
	/// <summary>
	/// Parses a message header. Does not yet process the annotations chunks and message data.
	/// </summary>
	public static Message from_header(byte[] header)
	{
		if(header==null || header.Length!=HEADER_SIZE)
			throw new PyroException("header data size mismatch");
		
		if(header[0]!='P'||header[1]!='Y'||header[2]!='R'||header[3]!='O') 
			throw new PyroException("invalid message");    		

		int version = (header[4] << 8)|header[5];
		if(version!=Config.PROTOCOL_VERSION)
			throw new PyroException("invalid protocol version: "+version);
		
		int msg_type = (header[6] << 8)|header[7];
		int flags = (header[8] << 8)|header[9];
		int seq = (header[10] << 8)|header[11];
		int data_size=(((((header[12] <<8) | header[13]) <<8) | header[14]) <<8) | header[15];
		int serializer_id = (header[16] << 8)|header[17];
		int annotations_size = (header[18]<<8)|header[19];
		// byte 20 and 21 are reserved.
		int checksum = (header[22]<<8)|header[23];
		if(checksum!=((msg_type+version+data_size+annotations_size+flags+serializer_id+seq+CHECKSUM_MAGIC)&0xffff))
			throw new PyroException("header checksum mismatch");
		
		var msg = new Message((ushort)msg_type, (ushort)serializer_id, (ushort)flags, (ushort)seq);
		msg.data_size = data_size;
		msg.annotations_size = (ushort)annotations_size;
		return msg;
	}
Example #17
0
        public void testHmac()
        {
            byte[] hk=Config.HMAC_KEY;
            Stream c;
            byte[] data;

            try {
            Config.HMAC_KEY = Encoding.ASCII.GetBytes("test key");
            data = new Message(Message.MSG_RESULT, new byte[]{1,2,3,4,5}, 42, 0, 1, null).to_bytes();
            c = new ConnectionMock(data);
            }
            finally {
            Config.HMAC_KEY = hk;
            }
            // test checking of different hmacs
            try {
            Message.recv(c, null);
            Assert.Fail("crash expected");
            }
            catch(PyroException x) {
            Assert.IsTrue(x.Message.Contains("hmac"));
            }
            c = new ConnectionMock(data);
            // test that it works again when resetting the key
            try {
            hk = Config.HMAC_KEY;
            Config.HMAC_KEY = Encoding.ASCII.GetBytes("test key");
            Message.recv(c, null);
            }
            finally {
            Config.HMAC_KEY = hk;
            }
            c = new ConnectionMock(data);
            // test that it doesn't work when no key is set
            try {
            hk = Config.HMAC_KEY;
            Config.HMAC_KEY = null;
            Message.recv(c, null);
            Assert.Fail("crash expected");
            }
            catch(PyroException x) {
            Assert.IsTrue(x.Message.Contains("hmac key config"));
            }
            finally {
            Config.HMAC_KEY = hk;
            }
        }
Example #18
0
        /// <summary>
        /// Internal call method to actually perform the Pyro method call and process the result.
        /// </summary>
        private object internal_call(string method, string actual_objectId, ushort flags, bool checkMethodName, params object[] parameters)
        {
            actual_objectId = actual_objectId ?? this.objectid;
            lock(this) {
            connect();
            unchecked {
                sequenceNr++;        // unchecked so this ushort wraps around 0-65535 instead of raising an OverflowException
            }
            }
            if(pyroAttrs.Contains(method)) {
            throw new PyroException("cannot call an attribute");
            }
            if(pyroOneway.Contains(method)) {
            flags |= Message.FLAGS_ONEWAY;
            }
            if(checkMethodName && Config.METADATA && !pyroMethods.Contains(method)) {
            throw new PyroException(string.Format("remote object '{0}' has no exposed attribute or method '{1}'", actual_objectId, method));
            }

            if (parameters == null)
            parameters = new object[] {};

            PyroSerializer ser = PyroSerializer.GetFor(Config.SERIALIZER);
            byte[] pickle = ser.serializeCall(actual_objectId, method, parameters, new Dictionary<string,object>(0));
            var msg = new Message(Message.MSG_INVOKE, pickle, ser.serializer_id, flags, sequenceNr, this.annotations(), pyroHmacKey);
            Message resultmsg;
            lock (this.sock) {
            IOUtil.send(sock_stream, msg.to_bytes());
            if(Config.MSG_TRACE_DIR!=null) {
                Message.TraceMessageSend(sequenceNr, msg.get_header_bytes(), msg.get_annotations_bytes(), msg.data);
            }
            pickle = null;

            if ((flags & Message.FLAGS_ONEWAY) != 0)
                return null;

            resultmsg = Message.recv(sock_stream, new ushort[]{Message.MSG_RESULT}, pyroHmacKey);
            }
            if (resultmsg.seq != sequenceNr) {
            throw new PyroException("result msg out of sync");
            }
            responseAnnotations(resultmsg.annotations, resultmsg.type);
            if ((resultmsg.flags & Message.FLAGS_COMPRESSED) != 0) {
            _decompressMessageData(resultmsg);
            }

            if ((resultmsg.flags & Message.FLAGS_EXCEPTION) != 0) {
            Exception rx = (Exception) ser.deserializeData(resultmsg.data);
            if (rx is PyroException) {
                throw (PyroException) rx;
            } else {
                PyroException px = new PyroException("remote exception occurred", rx);
                PropertyInfo remotetbProperty=rx.GetType().GetProperty("_pyroTraceback");
                if(remotetbProperty!=null) {
                    string remotetb=(string)remotetbProperty.GetValue(rx,null);
                    px._pyroTraceback=remotetb;
                }
                throw px;
            }
            }

            return ser.deserializeData(resultmsg.data);
        }
Example #19
0
 public void testMessageHeaderDatasize()
 {
     var msg = new Message(Message.MSG_RESULT, Encoding.ASCII.GetBytes("hello"), 12345, 60006, 30003, null);
     msg.data_size = 0x12345678;   // hack it to a large value to see if it comes back ok
     byte[] hdr = msg.to_bytes().Take(Message.HEADER_SIZE).ToArray();
     msg = Message.from_header(hdr);
     Assert.AreEqual(Message.MSG_RESULT, msg.type);
     Assert.AreEqual(60006, msg.flags);
     Assert.AreEqual(0x12345678, msg.data_size);
     Assert.AreEqual(12345, msg.serializer_id);
     Assert.AreEqual(30003, msg.seq);
 }
        /**
         * Receive a message from the connection. If you set requiredMsgType to the required
         * message type id instead of zero, it will check the incoming message type and
         * raise a PyroException if they don't match.
         */
        public static Message getMessage(Stream connection, int requiredMsgType)
        {
            byte[] headerdata=IOUtil.recv(connection, HEADER_SIZE);
            MessageHeader header=parseMessageHeader(headerdata);
            if(requiredMsgType!=0 && header.type!=requiredMsgType) {
            throw new PyroException("invalid msg type received: "+header.type);
            }
            byte[] data=IOUtil.recv(connection, header.datasize);
            if(Config.MSG_TRACE_DIR!=null) {
            TraceMessageRecv(header.sequence, headerdata, data);
            }
            if(((header.flags&FLAGS_HMAC) != 0) && (Config.HMAC_KEY!=null)) {
            if(header.hmac!=makeHMAC(data)) {
                throw new PyroException("message hmac mismatch");
            }
            } else if(((header.flags&FLAGS_HMAC) != 0) != (Config.HMAC_KEY!=null)) {
            throw new PyroException("hmac key config not symmetric");
            }

            Message msg=new Message();
            msg.type=header.type;
            msg.flags=header.flags;
            msg.sequence=header.sequence;
            msg.data=data;
            return msg;
        }
Example #21
0
        public void testHmac()
        {
            Stream c;
            byte[] data;

            data = new Message(Message.MSG_RESULT, new byte[]{1,2,3,4,5}, 42, 0, 1, null, Encoding.UTF8.GetBytes("secret")).to_bytes();
            c = new MemoryStream(data);

            // test checking of different hmacs
            try {
            Message.recv(c, null, Encoding.UTF8.GetBytes("wrong"));
            Assert.Fail("crash expected");
            }
            catch(PyroException x) {
            Assert.IsTrue(x.Message.Contains("hmac"));
            }
            c = new MemoryStream(data);
            // test that it works again when resetting the key
            Message.recv(c, null, Encoding.UTF8.GetBytes("secret"));

            c = new MemoryStream(data);
            // test that it doesn't work when no key is set
            try {
            Message.recv(c, null, null);
            Assert.Fail("crash expected");
            }
            catch(PyroException x) {
            Assert.IsTrue(x.Message.Contains("hmac key config"));
            }
        }