/** * Return how much bytes can be read out of the encrypted data. Be aware that this method will not * increase the readerIndex of the given {@link ByteBuf}. * * @param buffer The {@link ByteBuf} to read from. Be aware that it must have at least 5 bytes to * read, otherwise it will throw an {@link IllegalArgumentException}. * @return length The length of the encrypted packet that is included in the buffer. This will * return {@code -1} if the given {@link ByteBuf} is not encrypted at all. * @throws IllegalArgumentException Is thrown if the given {@link ByteBuf} has not at least 5 * bytes to read. */ private static int getEncryptedPacketLength(ByteBuf buffer, int offset) { int packetLength = 0; // SSLv3 or TLS - Check ContentType boolean tls; switch (buffer.getUnsignedByte(offset)) { case 20: // change_cipher_spec case 21: // alert case 22: // handshake case 23: // application_data tls = true; break; default: // SSLv2 or bad data tls = false; } if (tls) { // SSLv3 or TLS - Check ProtocolVersion int majorVersion = buffer.getUnsignedByte(offset + 1); if (majorVersion == 3) { // SSLv3 or TLS packetLength = buffer.getUnsignedShort(offset + 3) + 5; if (packetLength <= 5) { // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data) tls = false; } } else { // Neither SSLv3 or TLSv1 (i.e. SSLv2 or bad data) tls = false; } } if (!tls) { // SSLv2 or bad data - Check the version boolean sslv2 = true; int headerLength = (buffer.getUnsignedByte(offset) & 0x80) != 0 ? 2 : 3; int majorVersion = buffer.getUnsignedByte(offset + headerLength + 1); if (majorVersion == 2 || majorVersion == 3) { // SSLv2 if (headerLength == 2) { packetLength = (buffer.getShort(offset) & 0x7FFF) + 2; } else { packetLength = (buffer.getShort(offset) & 0x3FFF) + 3; } if (packetLength <= headerLength) { sslv2 = false; } } else { sslv2 = false; } if (!sslv2) { return -1; } } return packetLength; }
public QueryRequest(ByteBuf buffer) { super(buffer, kXR_query); reqcode = buffer.getUnsignedShort(4); fhandle = buffer.getInt(8); int alen = buffer.getInt(20); /* The protocol spec doesn't state anything about trailing zeros in args, * however the xrdfs client sends zero terminated paths. */ args = NULL_CHARACTER.trimTrailingFrom(buffer.toString(24, alen, US_ASCII)); }
public long decodeLength(ByteBuf in, int offset) throws Exception { if (discardingTooLongFrame) { long bytesToDiscard = this.bytesToDiscard; int localBytesToDiscard = (int) Math.min(bytesToDiscard, in.readableBytes()); in.skipBytes(localBytesToDiscard); bytesToDiscard -= localBytesToDiscard; this.bytesToDiscard = bytesToDiscard; failIfNecessary(false); } int readerIndex = in.readerIndex() + offset; short b = in.getUnsignedByte(readerIndex); int ubyte = b & 0xff; LOGGER.trace("message: " + toHex(ubyte)); switch (ubyte) { case NIL: return 1L; case FALSE: return 1L; case TRUE: return 1L; case BIN8: { short length = in.getUnsignedByte(readerIndex + 1); return 2L + length; } case BIN16: { int length = in.getUnsignedShort(readerIndex + 1); return 3L + length; } case BIN32: { long length = in.getUnsignedInt(readerIndex + 1); return 5L + length; } case EXT8: { short length = in.getUnsignedByte(readerIndex + 1); return 3L + length; } case EXT16: { int length = in.getUnsignedShort(readerIndex + 1); return 4L + length; } case EXT32: { long length = in.getUnsignedInt(readerIndex + 1); return 6L + length; } case FLOAT32: return 5L; case FLOAT64: return 9L; case UINT8: return 2L; case UINT16: return 3L; case UINT32: return 5L; case UINT64: return 9L; case INT8: return 2L; case INT16: return 3L; case INT32: return 5L; case INT64: return 9L; case FIXEXT1: return 3L; case FIXEXT2: return 4L; case FIXEXT4: return 6L; case FIXEXT8: return 10L; case FIXEXT16: return 18L; case STR8: { short length = in.getUnsignedByte(readerIndex + 1); return 2L + length; } case STR16: { int length = in.getUnsignedShort(readerIndex + 1); return 3L + length; } case STR32: { long length = in.getUnsignedInt(readerIndex + 1); return 5L + length; } case ARRAY16: { int elemCount = in.getUnsignedShort(readerIndex + 1); return getArraySize(in, 3, offset, elemCount); } case ARRAY32: { long elemCount = in.getUnsignedInt(readerIndex + 1); return getArraySize(in, 5, offset, elemCount); } case MAP16: { int elemCount = in.getUnsignedShort(readerIndex + 1); return getArraySize(in, 3, offset, elemCount * 2); } case MAP32: { long elemCount = in.getUnsignedInt(readerIndex + 1); return getArraySize(in, 5, offset, elemCount * 2); } default: if ((ubyte >> 7) == 0) { // positive fixint return 1L; } else if ((ubyte >> 4) == 0b1000) { // fixmap int elemCount = ubyte & 0b00001111; return getArraySize(in, 1, offset, elemCount * 2); } else if ((ubyte >> 4) == 0b1001) { // fixarray int elemCount = ubyte & 0b00001111; return getArraySize(in, 1, offset, elemCount); } else if ((ubyte >> 5) == 0b101) { // fixstr int length = ubyte & 0b00011111; return 1L + length; } else if ((ubyte >> 5) == 0b111) { // negative fixint return 1L; } else { throw new CorruptedFrameException("Unknown header byte of message: " + toHex(ubyte)); } } }
@Override public int getUnsignedShort(int index) { return buf.getUnsignedShort(index); }
public boolean decodePayload(final ByteBuf buf) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException { LOG.debug( "About to pass message {} to {}. Buffer to read: {}.", message, message.senderSocket(), buf.readableBytes()); if (!message.hasContent()) { return true; } // payload comes here int size; PublicKey receivedPublicKey; while (contentTypes.size() > 0) { Content content = contentTypes.peek(); LOG.debug("Parse content: {} in message {}", content, message); switch (content) { case INTEGER: if (buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } message.intValue(buf.readInt()); lastContent = contentTypes.poll(); break; case LONG: if (buf.readableBytes() < Utils.LONG_BYTE_SIZE) { return false; } message.longValue(buf.readLong()); lastContent = contentTypes.poll(); break; case KEY: if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE) { return false; } byte[] me = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me); message.key(new Number160(me)); lastContent = contentTypes.poll(); break; case BLOOM_FILTER: if (buf.readableBytes() < Utils.SHORT_BYTE_SIZE) { return false; } size = buf.getUnsignedShort(buf.readerIndex()); if (buf.readableBytes() < size) { return false; } message.bloomFilter(new SimpleBloomFilter<Number160>(buf)); lastContent = contentTypes.poll(); break; case SET_NEIGHBORS: if (neighborSize == -1 && buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } if (neighborSize == -1) { neighborSize = buf.readUnsignedByte(); } if (neighborSet == null) { neighborSet = new NeighborSet(-1, new ArrayList<PeerAddress>(neighborSize)); } for (int i = neighborSet.size(); i < neighborSize; i++) { if (buf.readableBytes() < Utils.SHORT_BYTE_SIZE) { return false; } int header = buf.getUnsignedShort(buf.readerIndex()); size = PeerAddress.size(header); if (buf.readableBytes() < size) { return false; } PeerAddress pa = new PeerAddress(buf); neighborSet.add(pa); } message.neighborsSet(neighborSet); lastContent = contentTypes.poll(); neighborSize = -1; neighborSet = null; break; case SET_PEER_SOCKET: if (peerSocketAddressSize == -1 && buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } if (peerSocketAddressSize == -1) { peerSocketAddressSize = buf.readUnsignedByte(); } if (peerSocketAddresses == null) { peerSocketAddresses = new ArrayList<PeerSocketAddress>(peerSocketAddressSize); } for (int i = peerSocketAddresses.size(); i < peerSocketAddressSize; i++) { if (buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } int header = buf.getUnsignedByte(buf.readerIndex()); boolean isIPv4 = header == 0; size = PeerSocketAddress.size(isIPv4); if (buf.readableBytes() < size + Utils.BYTE_BYTE_SIZE) { return false; } // skip the ipv4/ipv6 header buf.skipBytes(1); peerSocketAddresses.add(PeerSocketAddress.create(buf, isIPv4)); } message.peerSocketAddresses(peerSocketAddresses); lastContent = contentTypes.poll(); peerSocketAddressSize = -1; peerSocketAddresses = null; break; case SET_KEY640: if (keyCollectionSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (keyCollectionSize == -1) { keyCollectionSize = buf.readInt(); } if (keyCollection == null) { keyCollection = new KeyCollection(new ArrayList<Number640>(keyCollectionSize)); } for (int i = keyCollection.size(); i < keyCollectionSize; i++) { if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE) { return false; } byte[] me2 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me2); Number160 locationKey = new Number160(me2); buf.readBytes(me2); Number160 domainKey = new Number160(me2); buf.readBytes(me2); Number160 contentKey = new Number160(me2); buf.readBytes(me2); Number160 versionKey = new Number160(me2); keyCollection.add(new Number640(locationKey, domainKey, contentKey, versionKey)); } message.keyCollection(keyCollection); lastContent = contentTypes.poll(); keyCollectionSize = -1; keyCollection = null; break; case MAP_KEY640_DATA: if (mapSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (mapSize == -1) { mapSize = buf.readInt(); } if (dataMap == null) { dataMap = new DataMap(new TreeMap<Number640, Data>()); } if (data != null) { if (!data.decodeBuffer(buf)) { return false; } if (!data.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } data = null; key = null; } for (int i = dataMap.size(); i < mapSize; i++) { if (key == null) { if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE) { return false; } byte[] me3 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me3); Number160 locationKey = new Number160(me3); buf.readBytes(me3); Number160 domainKey = new Number160(me3); buf.readBytes(me3); Number160 contentKey = new Number160(me3); buf.readBytes(me3); Number160 versionKey = new Number160(me3); key = new Number640(locationKey, domainKey, contentKey, versionKey); } LOG.debug("Key decoded in message {}, remaining {}", message, buf.readableBytes()); data = Data.decodeHeader(buf, signatureFactory); if (data == null) { return false; } LOG.debug("Header decoded in message {}, remaining {}", message, buf.readableBytes()); dataMap.dataMap().put(key, data); if (!data.decodeBuffer(buf)) { return false; } LOG.debug("Buffer decoded in message {}", message); if (!data.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } LOG.debug("Done decoded in message {}", message); // if we have signed the message, set the public key anyway, but only if we indicated so inheritPublicKey(message, data); data = null; key = null; } message.setDataMap(dataMap); lastContent = contentTypes.poll(); mapSize = -1; dataMap = null; break; case MAP_KEY640_KEYS: if (keyMap640KeysSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (keyMap640KeysSize == -1) { keyMap640KeysSize = buf.readInt(); } if (keyMap640Keys == null) { keyMap640Keys = new KeyMap640Keys(new TreeMap<Number640, Collection<Number160>>()); } final int meta = Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE; for (int i = keyMap640Keys.size(); i < keyMap640KeysSize; i++) { if (buf.readableBytes() < meta + Utils.BYTE_BYTE_SIZE) { return false; } size = buf.getUnsignedByte(buf.readerIndex() + meta); if (buf.readableBytes() < meta + Utils.BYTE_BYTE_SIZE + (size * Number160.BYTE_ARRAY_SIZE)) { return false; } byte[] me3 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me3); Number160 locationKey = new Number160(me3); buf.readBytes(me3); Number160 domainKey = new Number160(me3); buf.readBytes(me3); Number160 contentKey = new Number160(me3); buf.readBytes(me3); Number160 versionKey = new Number160(me3); int numBasedOn = buf.readByte(); Set<Number160> value = new HashSet<Number160>(numBasedOn); for (int j = 0; j < numBasedOn; j++) { buf.readBytes(me3); Number160 basedOnKey = new Number160(me3); value.add(basedOnKey); } keyMap640Keys.put(new Number640(locationKey, domainKey, contentKey, versionKey), value); } message.keyMap640Keys(keyMap640Keys); lastContent = contentTypes.poll(); keyMap640KeysSize = -1; keyMap640Keys = null; break; case MAP_KEY640_BYTE: if (keyMapByteSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (keyMapByteSize == -1) { keyMapByteSize = buf.readInt(); } if (keyMapByte == null) { keyMapByte = new KeyMapByte(new HashMap<Number640, Byte>(2 * keyMapByteSize)); } for (int i = keyMapByte.size(); i < keyMapByteSize; i++) { if (buf.readableBytes() < Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + Number160.BYTE_ARRAY_SIZE + 1) { return false; } byte[] me3 = new byte[Number160.BYTE_ARRAY_SIZE]; buf.readBytes(me3); Number160 locationKey = new Number160(me3); buf.readBytes(me3); Number160 domainKey = new Number160(me3); buf.readBytes(me3); Number160 contentKey = new Number160(me3); buf.readBytes(me3); Number160 versionKey = new Number160(me3); byte value = buf.readByte(); keyMapByte.put(new Number640(locationKey, domainKey, contentKey, versionKey), value); } message.keyMapByte(keyMapByte); lastContent = contentTypes.poll(); keyMapByteSize = -1; keyMapByte = null; break; case BYTE_BUFFER: if (bufferSize == -1 && buf.readableBytes() < Utils.INTEGER_BYTE_SIZE) { return false; } if (bufferSize == -1) { bufferSize = buf.readInt(); } if (buffer == null) { buffer = new DataBuffer(); } final int remaining = bufferSize - bufferTransferred; bufferTransferred += buffer.transferFrom(buf, remaining); if (bufferTransferred < bufferSize) { LOG.debug( "Still looking for data. Indicating that its not finished yet. Already Transferred = {}, Size = {}.", bufferTransferred, bufferSize); return false; } message.buffer(new Buffer(buffer.toByteBuf(), bufferSize)); lastContent = contentTypes.poll(); bufferSize = -1; bufferTransferred = 0; buffer = null; break; case SET_TRACKER_DATA: if (trackerDataSize == -1 && buf.readableBytes() < Utils.BYTE_BYTE_SIZE) { return false; } if (trackerDataSize == -1) { trackerDataSize = buf.readUnsignedByte(); } if (trackerData == null) { trackerData = new TrackerData(new HashMap<PeerAddress, Data>(2 * trackerDataSize)); } if (currentTrackerData != null) { if (!currentTrackerData.decodeBuffer(buf)) { return false; } if (!currentTrackerData.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } currentTrackerData = null; } for (int i = trackerData.size(); i < trackerDataSize; i++) { if (buf.readableBytes() < Utils.SHORT_BYTE_SIZE) { return false; } int header = buf.getUnsignedShort(buf.readerIndex()); size = PeerAddress.size(header); if (buf.readableBytes() < size) { return false; } PeerAddress pa = new PeerAddress(buf); currentTrackerData = Data.decodeHeader(buf, signatureFactory); if (currentTrackerData == null) { return false; } trackerData.peerAddresses().put(pa, currentTrackerData); if (message.isSign()) { currentTrackerData.publicKey(message.publicKey(0)); } if (!currentTrackerData.decodeBuffer(buf)) { return false; } if (!currentTrackerData.decodeDone(buf, message.publicKey(0), signatureFactory)) { return false; } currentTrackerData = null; } message.trackerData(trackerData); lastContent = contentTypes.poll(); trackerDataSize = -1; trackerData = null; break; case PUBLIC_KEY: // fall-through case PUBLIC_KEY_SIGNATURE: receivedPublicKey = signatureFactory.decodePublicKey(buf); if (content == Content.PUBLIC_KEY_SIGNATURE) { if (receivedPublicKey == PeerBuilder.EMPTY_PUBLIC_KEY) { throw new InvalidKeyException("The public key cannot be empty."); } } if (receivedPublicKey == null) { return false; } message.publicKey(receivedPublicKey); lastContent = contentTypes.poll(); break; default: break; } } LOG.debug("Parsed content in message {}", message); if (message.isSign()) { size = signatureFactory.signatureSize(); if (buf.readableBytes() < size) { return false; } SignatureCodec signatureEncode = signatureFactory.signatureCodec(buf); message.receivedSignature(signatureEncode); } return true; }
@Override public int getUnsignedShort(int var1) { return a.getUnsignedShort(var1); }