Example #1
0
  /**
   * 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;
  }
Example #2
0
  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));
        }
    }
  }
Example #4
0
 @Override
 public int getUnsignedShort(int index) {
   return buf.getUnsignedShort(index);
 }
Example #5
0
  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);
 }