Ejemplo n.º 1
0
  /**
   * Handle MCS info from server (server info, encryption info and channel information)
   *
   * @param mcs_data Data received from server
   */
  public void processMcsData(RdpPacket_Localised mcs_data)
      throws RdesktopException, CryptoException {
    logger.debug("Secure.processMcsData");
    int tag = 0, len = 0, length = 0, nexttag = 0;

    mcs_data.incrementPosition(21); // header (T.124 stuff, probably)
    len = mcs_data.get8();

    if ((len & 0x00000080) != 0) {
      len = mcs_data.get8();
    }

    while (mcs_data.getPosition() < mcs_data.getEnd()) {
      tag = mcs_data.getLittleEndian16();
      length = mcs_data.getLittleEndian16();

      if (length <= 4) return;

      nexttag = mcs_data.getPosition() + length - 4;

      switch (tag) {
        case (Secure.SEC_TAG_SRV_INFO):
          processSrvInfo(mcs_data);
          break;
        case (Secure.SEC_TAG_SRV_CRYPT):
          this.processCryptInfo(mcs_data);
          break;
        case (Secure.SEC_TAG_SRV_CHANNELS):
          /*
           * FIXME: We should parse this information and use it to map
           * RDP5 channels to MCS channels
           */
          break;

        default:
          throw new RdesktopException("Not implemented! Tag:" + tag + "not recognized!");
      }

      mcs_data.setPosition(nexttag);
    }
  }
Ejemplo n.º 2
0
  /**
   * Read encryption information from a Secure layer PDU, obtaining and storing level of encryption
   * and any keys received
   *
   * @param data Packet to read encryption information from
   * @return Size of RC4 key
   * @throws RdesktopException
   */
  public int parseCryptInfo(RdpPacket_Localised data) throws RdesktopException {
    logger.debug("Secure.parseCryptInfo");
    int encryption_level = 0, random_length = 0, RSA_info_length = 0;
    int tag = 0, length = 0;
    int next_tag = 0, end = 0;
    int rc4_key_size = 0;

    rc4_key_size = data.getLittleEndian32(); // 1 = 40-Bit 2 = 128 Bit
    encryption_level = data.getLittleEndian32(); // 1 = low, 2 = medium,
    // 3 = high
    if (encryption_level == 0) { // no encryption
      return 0;
    }
    random_length = data.getLittleEndian32();
    RSA_info_length = data.getLittleEndian32();

    if (random_length != SEC_RANDOM_SIZE) {
      throw new RdesktopException(
          "Wrong Size of Random! Got" + random_length + "expected" + SEC_RANDOM_SIZE);
    }
    this.server_random = new byte[random_length];
    data.copyToByteArray(this.server_random, 0, data.getPosition(), random_length);
    data.incrementPosition(random_length);

    end = data.getPosition() + RSA_info_length;

    if (end > data.getEnd()) {
      logger.debug("Reached end of crypt info prematurely ");
      return 0;
    }

    // data.incrementPosition(12); // unknown bytes
    int flags = data.getLittleEndian32(); // in_uint32_le(s, flags); // 1
    // = RDP4-style, 0x80000002 =
    // X.509
    logger.debug("Flags = 0x" + Integer.toHexString(flags));
    if ((flags & 1) != 0) {
      logger.debug(("We're going for the RDP4-style encryption"));
      data.incrementPosition(8); // in_uint8s(s, 8); // unknown

      while (data.getPosition() < data.getEnd()) {
        tag = data.getLittleEndian16();
        length = data.getLittleEndian16();

        next_tag = data.getPosition() + length;

        switch (tag) {
          case (Secure.SEC_TAG_PUBKEY):
            if (!parsePublicKey(data)) {
              return 0;
            }

            break;
          case (Secure.SEC_TAG_KEYSIG):
            // Microsoft issued a key but we don't care
            break;

          default:
            throw new RdesktopException("Unimplemented decrypt tag " + tag);
        }
        data.setPosition(next_tag);
      }

      if (data.getPosition() == data.getEnd()) {
        return rc4_key_size;
      } else {
        logger.warn("End not reached!");
        return 0;
      }

    } else {
      logger.debug(("We're going for the RDP5-style encryption"));
      // data.incrementPosition(4); // number of certificates
      int num_certs = data.getLittleEndian32();

      int cacert_len = data.getLittleEndian32();
      data.incrementPosition(cacert_len);
      int cert_len = data.getLittleEndian32();
      data.incrementPosition(cert_len);

      readCert = true;

      return rc4_key_size;
    }
  }
Ejemplo n.º 3
0
 /**
  * Read server info from packet, specifically the RDP version of the server
  *
  * @param mcs_data Packet to read
  */
 private void processSrvInfo(RdpPacket_Localised mcs_data) {
   Options.server_rdp_version = mcs_data.getLittleEndian16(); // in_uint16_le(s,
   // g_server_rdp_version);
   logger.debug(("Server RDP version is " + Options.server_rdp_version));
   if (1 == Options.server_rdp_version) Options.use_rdp5 = false;
 }