protected void decode(ChannelHandlerContext paramChannelHandlerContext, ByteBuf paramByteBuf, List<Object> paramList) throws Exception { paramByteBuf.markReaderIndex(); byte[] arrayOfByte = new byte[5]; for(int i = 0; i < arrayOfByte.length; i++) { if(!paramByteBuf.isReadable()) { paramByteBuf.resetReaderIndex(); return; } arrayOfByte[i] = paramByteBuf.readByte(); if(arrayOfByte[i] >= 0) { int j = CodedInputStream.newInstance(arrayOfByte, 0, i + 1).readRawVarint32(); if(j < 0) { throw new CorruptedFrameException("negative length: " + j); } if(paramByteBuf.readableBytes() < j) { paramByteBuf.resetReaderIndex(); return; } paramList.add(paramByteBuf.readBytes(j)); return; } } throw new CorruptedFrameException("length wider than 32-bit"); }
/** * Populate the message with couple of Qos, topic */ private void decodeSubscription(ByteBuf in, SubscribeMessage message) throws UnsupportedEncodingException { String topic = Utils.decodeString(in); //check topic is at least one char [MQTT-4.7.3-1] if (topic.length() == 0) { throw new CorruptedFrameException("Received a SUBSCRIBE with empty topic filter"); } byte qosByte = in.readByte(); if ((qosByte & 0xFC) > 0) { //the first 6 bits is reserved => has to be 0 throw new CorruptedFrameException("subscribe MUST have QoS byte with reserved buts to 0, found " + Integer.toHexString(qosByte)); } byte qos = (byte) (qosByte & 0x03); //TODO check qos id 000000xx message.addSubscription(new SubscribeMessage.Couple(qos, topic)); }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { in.markReaderIndex(); if (!Utils.checkHeaderAvailability(in)) { in.resetReaderIndex(); return; } in.resetReaderIndex(); byte messageType = Utils.readMessageType(in); DemuxDecoder decoder = m_decoderMap.get(messageType); if (decoder == null) { throw new CorruptedFrameException("Can't find any suitable decoder for message type: " + messageType); } decoder.decode(ctx, in, out); }
/** * Encode the value in the format defined in specification as variable length * array. * * @throws IllegalArgumentException if the value is not in the specification bounds * [0..268435455]. */ static ByteBuf encodeRemainingLength(int value) throws CorruptedFrameException { if (value > MAX_LENGTH_LIMIT || value < 0) { throw new CorruptedFrameException("Value should in range 0.." + MAX_LENGTH_LIMIT + " found " + value); } ByteBuf encoded = Unpooled.buffer(4); byte digit; do { digit = (byte) (value % 128); value = value / 128; // if there are more digits to encode, set the top bit of this digit if (value > 0) { digit = (byte) (digit | 0x80); } encoded.writeByte(digit); } while (value > 0); return encoded; }
@Test(expected = CorruptedFrameException.class) public void testFailureDecodeBadRsa() throws Exception { // Decode our bad RSA key KeyFactory keyFactory = KeyFactory.getInstance("RSA"); X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(TestVotifierPlugin.r("/bad_public.key")); PublicKey badPublicKey = keyFactory.generatePublic(publicKeySpec); // Send the bad vote EmbeddedChannel channel = createChannel(); byte[] encrypted = VoteUtil.encodePOJOv1(new Vote("Test", "test", "test", "test"), badPublicKey); ByteBuf encryptedByteBuf = Unpooled.wrappedBuffer(encrypted); try { channel.writeInbound(encryptedByteBuf); } finally { channel.close(); } }
/** * Encode the value in the format defined in specification as variable length array. * * @throws IllegalArgumentException * if the value is not in the specification bounds [0..268435455]. */ static ByteBuf encodeRemainingLength(int value) throws CorruptedFrameException { if (value > MAX_LENGTH_LIMIT || value < 0) { throw new CorruptedFrameException("Value should in range 0.." + MAX_LENGTH_LIMIT + " found " + value); } ByteBuf encoded = Unpooled.buffer(4); byte digit; do { digit = (byte) (value % 128); value = value / 128; // if there are more digits to encode, set the top bit of this digit if (value > 0) { digit = (byte) (digit | 0x80); } encoded.writeByte(digit); } while (value > 0); return encoded; }
private void decode(ByteBuf in, List<Object> out) throws Exception { in.markReaderIndex(); if (!Utils.checkHeaderAvailability(in)) { in.resetReaderIndex(); return; } in.resetReaderIndex(); byte messageType = Utils.readMessageType(in); DemuxDecoder decoder = m_decoderMap.get(messageType); if (decoder == null) { throw new CorruptedFrameException("Can't find any suitable decoder for message type: " + messageType); } decoder.decode(in, out); }
@Override void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { //Common decoding part in.resetReaderIndex(); UnsubscribeMessage message = new UnsubscribeMessage(); if (!decodeCommonHeader(message, in)) { in.resetReaderIndex(); return; } //check qos level if (message.getQos() != AbstractMessage.QOSType.LEAST_ONE) { throw new CorruptedFrameException("Found an Usubscribe message with qos other than LEAST_ONE, was: " + message.getQos()); } int start = in.readerIndex(); //read messageIDs message.setMessageID(in.readUnsignedShort()); int readed = in.readerIndex()- start; while (readed < message.getRemainingLength()) { message.addTopic(Utils.decodeString(in)); readed = in.readerIndex()- start; } out.add(message); }
@Override void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { //Common decoding part SubscribeMessage message = new SubscribeMessage(); in.resetReaderIndex(); if (!decodeCommonHeader(message, in)) { in.resetReaderIndex(); return; } //check qos level if (message.getQos() != QOSType.LEAST_ONE) { throw new CorruptedFrameException("Received Subscribe message with QoS other than LEAST_ONE, was: " + message.getQos()); } int start = in.readerIndex(); //read messageIDs message.setMessageID(in.readUnsignedShort()); int readed = in.readerIndex() - start; while (readed < message.getRemainingLength()) { decodeSubscription(in, message); readed = in.readerIndex()- start; } out.add(message); }
@Test(expected = CorruptedFrameException.class) public void testBadFlagUserPwd() throws UnsupportedEncodingException, Exception { m_buff = Unpooled.buffer(14); m_buff.writeByte((AbstractMessage.CONNECT << 4)).writeByte(12); //Proto name encodeString(m_buff, "MQIsdp"); //version m_buff.writeByte(3); //conn flags m_buff.writeByte(0x4E); //sets user to false and password to true //keepAlive m_buff.writeByte(0).writeByte(0x0A); List<Object> results = new ArrayList<Object >(); //Excercise m_msgdec.decode(null, m_buff, results); }
protected void decode(ChannelHandlerContext context, ByteBuf in, List<Object> out) throws Exception { in.markReaderIndex(); for(int i = 0; i < 3; i++) { if(!in.isReadable(i + 1)) { in.resetReaderIndex(); return; } if(in.getByte(in.readerIndex() + i) < 0) { continue; } int size = BufferUtils.readVarInt(in); if(size > in.readableBytes()) { in.resetReaderIndex(); return; } out.add(in.readBytes(size)); return; } throw new CorruptedFrameException("VarInt size is longer than 21-bit"); }
public static int readRawVarint32(ByteBufInputStream is) throws IOException { byte tmp = is.readByte(); if (tmp >= 0) { return tmp; } int result = tmp & 0x7f; if ((tmp = is.readByte()) >= 0) { result |= tmp << 7; } else { result |= (tmp & 0x7f) << 7; if ((tmp = is.readByte()) >= 0) { result |= tmp << 14; } else { result |= (tmp & 0x7f) << 14; if ((tmp = is.readByte()) >= 0) { result |= tmp << 21; } else { result |= (tmp & 0x7f) << 21; result |= (tmp = is.readByte()) << 28; if (tmp < 0) { // Discard upper 32 bits. for (int i = 0; i < 5; i++) { if (is.readByte() >= 0) { return result; } } throw new CorruptedFrameException("Encountered a malformed varint."); } } } } return result; }
@Override protected void decode( ChannelHandlerContext channelHandlerContext, ByteBuf input, List<Object> output ) throws Exception { input.markReaderIndex(); byte[] bytes = new byte[3]; for ( int i = 0; i < bytes.length; i++ ) { if ( !input.isReadable() ) { input.resetReaderIndex(); return; } bytes[i] = input.readByte(); if ( bytes[i] >= 0 ) { ByteBuf buf = Unpooled.wrappedBuffer( bytes ); try { int j = Message.readVarInt( buf ); if ( input.readableBytes() < j ) { input.resetReaderIndex(); return; } output.add( input.readBytes( j ) ); return; } finally { buf.release(); } } } throw new CorruptedFrameException( "length wider than 21-bit" ); }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (!ctx.channel().isOpen()) { if (in.readableBytes() > 0) { logger.info("Channel is closed, discarding remaining {} byte(s) in buffer.", in.readableBytes()); } in.skipBytes(in.readableBytes()); return; } in.markReaderIndex(); /** * a variable-width message length can be up to five bytes in length. read bytes until we have a length. */ final byte[] buf = new byte[5]; int length = 0; for (int i = 0; i < buf.length; i++) { if (!in.isReadable()) { in.resetReaderIndex(); return; } buf[i] = in.readByte(); if (buf[i] >= 0) { length = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32(); if (length < 0) { throw new CorruptedFrameException("negative length: " + length); } if (length == 0) { throw new CorruptedFrameException("Received a message of length 0."); } if (in.readableBytes() < length) { in.resetReaderIndex(); return; } else { // complete message in buffer. break; } } } final ByteBuf frame = in.slice(in.readerIndex(), length); try { final InboundRpcMessage message = decodeMessage(ctx, frame, length); if (message != null) { out.add(message); } } finally { in.skipBytes(length); } }
@Override public SubscribeMessage decode(AttributeMap ctx, ByteBuf in) throws Exception { //Common decoding part SubscribeMessage message = new SubscribeMessage(); in.resetReaderIndex(); if (!decodeCommonHeader(message, 0x02, in)) { in.resetReaderIndex(); return null; } //check qos level if (message.getQos() != AbstractMessage.QOSType.LEAST_ONE) { throw new CorruptedFrameException("Received SUBSCRIBE message with QoS other than LEAST_ONE, was: " + message.getQos()); } int start = in.readerIndex(); //read messageIDs message.setMessageID(in.readUnsignedShort()); int read = in.readerIndex() - start; while (read < message.getRemainingLength()) { decodeSubscription(in, message); read = in.readerIndex() - start; } if (message.subscriptions().isEmpty()) { throw new CorruptedFrameException("subscribe MUST have got at least 1 couple topic/QoS"); } return message; }
private boolean genericDecodeCommonHeader(AbstractMessage message, Integer expectedFlagsOpt, ByteBuf in) { //Common decoding part if (in.readableBytes() < 2) { return false; } byte h1 = in.readByte(); byte messageType = (byte) ((h1 & 0x00F0) >> 4); byte flags = (byte) (h1 & 0x0F); if (expectedFlagsOpt != null) { int expectedFlags = expectedFlagsOpt; if ((byte) expectedFlags != flags) { String hexExpected = Integer.toHexString(expectedFlags); String hexReceived = Integer.toHexString(flags); throw new CorruptedFrameException(String.format("Received a message with fixed header flags (%s) != expected (%s)", hexReceived, hexExpected)); } } boolean dupFlag = ((byte) ((h1 & 0x0008) >> 3) == 1); byte qosLevel = (byte) ((h1 & 0x0006) >> 1); boolean retainFlag = ((byte) (h1 & 0x0001) == 1); int remainingLength = Utils.decodeRemainingLength(in); if (remainingLength == -1) { return false; } message.setMessageType(messageType); message.setDupFlag(dupFlag); try { message.setQos(AbstractMessage.QOSType.valueOf(qosLevel)); } catch (IllegalArgumentException e) { throw new CorruptedFrameException(String.format("Received an invalid QOS: %s", e.getMessage()), e); } message.setRetainFlag(retainFlag); message.setRemainingLength(remainingLength); return true; }
@Override protected void decode(final ChannelHandlerContext context, final ByteBuf byteBuf, final List<Object> objects) { byteBuf.markReaderIndex(); final byte[] arrayOfByte = new byte[3]; for (int i = 0; i < arrayOfByte.length; i++) { if (! byteBuf.isReadable()) { byteBuf.resetReaderIndex(); return; } arrayOfByte[i] = byteBuf.readByte(); if (arrayOfByte[i] >= 0) { final PacketDataSerializer dataSerializer = new PacketDataSerializer(Unpooled.wrappedBuffer(arrayOfByte)); try { final int size = dataSerializer.readVarInt(); if (byteBuf.readableBytes() < size) { byteBuf.resetReaderIndex(); return; } objects.add(byteBuf.readBytes(size)); return; } finally { dataSerializer.release(); } } } throw new CorruptedFrameException("length wider than 21-bit"); }
@Override void decode(AttributeMap ctx, ByteBuf in, List<Object> out) throws Exception { //Common decoding part in.resetReaderIndex(); UnsubscribeMessage message = new UnsubscribeMessage(); if (!decodeCommonHeader(message, 0x02, in)) { in.resetReaderIndex(); return; } //check qos level if (message.getQos() != AbstractMessage.QOSType.LEAST_ONE) { throw new CorruptedFrameException("Found an Unsubscribe message with qos other than LEAST_ONE, was: " + message.getQos()); } int start = in.readerIndex(); //read messageIDs message.setMessageID(in.readUnsignedShort()); int read = in.readerIndex() - start; while (read < message.getRemainingLength()) { String topicFilter = Utils.decodeString(in); //check topic is at least one char [MQTT-4.7.3-1] if (topicFilter.length() == 0) { throw new CorruptedFrameException("Received an UNSUBSCRIBE with empty topic filter"); } message.addTopicFilter(topicFilter); read = in.readerIndex() - start; } if (message.topicFilters().isEmpty()) { throw new CorruptedFrameException("unsubscribe MUST have got at least 1 topic"); } out.add(message); }
@Override void decode(AttributeMap ctx, ByteBuf in, List<Object> out) throws Exception { //Common decoding part SubscribeMessage message = new SubscribeMessage(); in.resetReaderIndex(); if (!decodeCommonHeader(message, 0x02, in)) { in.resetReaderIndex(); return; } //check qos level if (message.getQos() != QOSType.LEAST_ONE) { throw new CorruptedFrameException("Received SUBSCRIBE message with QoS other than LEAST_ONE, was: " + message.getQos()); } int start = in.readerIndex(); //read messageIDs message.setMessageID(in.readUnsignedShort()); int read = in.readerIndex() - start; while (read < message.getRemainingLength()) { decodeSubscription(in, message); read = in.readerIndex() - start; } if (message.subscriptions().isEmpty()) { throw new CorruptedFrameException("subscribe MUST have got at least 1 couple topic/QoS"); } out.add(message); }
/** * Populate the message with couple of Qos, topic */ private void decodeSubscription(ByteBuf in, SubscribeMessage message) throws UnsupportedEncodingException { String topic = Utils.decodeString(in); //check topic is at least one char [MQTT-4.7.3-1] if (topic.length() == 0) { throw new CorruptedFrameException("Received a SUBSCRIBE with empty topic filter"); } byte qosByte = in.readByte(); if ((qosByte & 0xFC) > 0) { //the first 6 bits is reserved => has to be 0 throw new CorruptedFrameException("subscribe MUST have QoS byte with reserved buts to 0, found " + Integer.toHexString(qosByte)); } byte qos = (byte)(qosByte & 0x03); //TODO check qos id 000000xx message.addSubscription(new SubscribeMessage.Couple(qos, topic)); }
@Override protected void encode(ChannelHandlerContext chc, AbstractMessage msg, ByteBuf bb) throws Exception { DemuxEncoder encoder = m_encoderMap.get(msg.getMessageType()); if (encoder == null) { throw new CorruptedFrameException("Can't find any suitable decoder for message type: " + msg.getMessageType()); } encoder.encode(chc, msg, bb); }
private boolean genericDecodeCommonHeader(AbstractMessage message, Integer expectedFlagsOpt, ByteBuf in) { //Common decoding part if (in.readableBytes() < 2) { return false; } byte h1 = in.readByte(); byte messageType = (byte) ((h1 & 0x00F0) >> 4); byte flags = (byte) (h1 & 0x0F); if (expectedFlagsOpt != null) { int expectedFlags = expectedFlagsOpt; if ((byte) expectedFlags != flags) { String hexExpected = Integer.toHexString(expectedFlags); String hexReceived = Integer.toHexString(flags); throw new CorruptedFrameException(String.format("Received a message with fixed header flags (%s) != expected (%s)", hexReceived, hexExpected)); } } boolean dupFlag = ((byte) ((h1 & 0x0008) >> 3) == 1); byte qosLevel = (byte) ((h1 & 0x0006) >> 1); boolean retainFlag = ((byte) (h1 & 0x0001) == 1); int remainingLength = Utils.decodeRemainingLenght(in); if (remainingLength == -1) { return false; } message.setMessageType(messageType); message.setDupFlag(dupFlag); try { message.setQos(AbstractMessage.QOSType.valueOf(qosLevel)); } catch(IllegalArgumentException e) { throw new CorruptedFrameException(String.format("Received an invalid QOS: %s", e.getMessage()), e); } message.setRetainFlag(retainFlag); message.setRemainingLength(remainingLength); return true; }
@Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { if (cause instanceof CorruptedFrameException) { //something goes bad with decoding LOG.warn("Error decoding a packet, probably a bad formatted packet, message: " + cause.getMessage()); } else { LOG.error("Ugly error on networking", cause); } ctx.close(); }