示例#1
0
    def parseConnectionPDU(self, data: bytes, length: int,
                           name: str) -> Tuple[int, int, int, bytes]:
        """
        Parse the provided data to extract common information contained in Connection Request, Connection Confirm and Disconnect Request PDUs.
        :param data: bytes to parse.
        :param length: Length of the Connection PDU.
        :param name: For debugging purposes: the name of the connection PDU (like "Connection Request").
        :return: A tuple of the information we find in both connection PDUs: (source, destination, options, payload)
        """

        if length < 6:
            raise ParsingError(
                "Invalid X244 %s length indicator: indicator = %d, expected at least 6 bytes"
                % (name, 6))

        destination = Uint16BE.unpack(data[2:4])
        source = Uint16BE.unpack(data[4:6])
        options = Uint8.unpack(data[6])
        payload = data[7:]

        if len(payload) != length - 6:
            raise ParsingError(
                "Invalid X224 %s payload length: expected = %d, length = %d" %
                (name, length - 6, len(payload)))

        return source, destination, options, payload
示例#2
0
 def writeChannelJoinRequest(self, stream: BytesIO, pdu: MCSChannelJoinRequestPDU):
     """
     Encode a Channel Join Request PDU
     :param stream: The destination stream to write into.
     :param pdu: the PDU to encode.
     """
     stream.write(Uint16BE.pack(pdu.initiator - MCSChannelID.USERCHANNEL_BASE))
     stream.write(Uint16BE.pack(pdu.channelID))
     stream.write(pdu.payload)
示例#3
0
 def writeConnectionPDU(self, stream: BytesIO, header: X224PDUType,
                        destination: int, source: int, options: int):
     """
     Write a connection PDU (connectionRequest/connectionConfirm/disconnectRequest) in the provided byte stream.
     """
     stream.write(Uint8.pack(header))
     stream.write(Uint16BE.pack(destination))
     stream.write(Uint16BE.pack(source))
     stream.write(Uint8.pack(options))
示例#4
0
 def writeDataPDU(self, stream: BytesIO, pdu: Union[MCSSendDataRequestPDU, MCSSendDataIndicationPDU]):
     """
     Encode a Data PDU
     :param stream: The destination stream to write into.
     :param pdu: the PDU to encode.
     """
     stream.write(Uint16BE.pack(pdu.initiator - MCSChannelID.USERCHANNEL_BASE))
     stream.write(Uint16BE.pack(pdu.channelID))
     stream.write(per.writeEnumeration(pdu.priority))
     stream.write(per.writeOctetStream(pdu.payload))
示例#5
0
 def parseDataPDU(self, stream: BytesIO, PDUClass: type) -> Union[MCSSendDataRequestPDU, MCSSendDataIndicationPDU]:
     """
     Common logic for parsing Send Data Request and Send Data Indication PDUs
     :param stream: stream containing the data
     :param PDUClass: the actual PDU class: MCSSendDataRequestPDU or MCSSendDataIndicationPDU
     """
     initiator = Uint16BE.unpack(stream.read(2)) + MCSChannelID.USERCHANNEL_BASE
     channelID = Uint16BE.unpack(stream.read(2))
     priority = per.readEnumeration(stream)
     payload = per.readOctetStream(stream)
     return PDUClass(initiator, channelID, priority, payload)
示例#6
0
    def writeChannelJoinConfirm(self, stream: BytesIO, pdu: MCSChannelJoinConfirmPDU):
        """
        Encode a Channel Join Confirm PDU
        :param stream: The destination stream to write into.
        :param pdu: the confirmation PDU.
        """
        stream.write(per.writeEnumeration(pdu.result))
        stream.write(Uint16BE.pack(pdu.initiator - MCSChannelID.USERCHANNEL_BASE))
        stream.write(Uint16BE.pack(pdu.requested))

        if pdu.channelID is not None:
            stream.write(Uint16BE.pack(pdu.channelID))
            stream.write(pdu.payload)
示例#7
0
    def parseChannelJoinRequest(self, stream: BytesIO) -> MCSChannelJoinRequestPDU:
        """
        Parse a Channel Join Request PDU
        :param stream: stream containing the data
        """
        data = stream.read()
        if len(data) < 4:
            raise ParsingError("Invalid Channel Join Request PDU received")

        initiator = Uint16BE.unpack(data[0 : 2]) + MCSChannelID.USERCHANNEL_BASE
        channelID = Uint16BE.unpack(data[2 : 4])
        payload = data[4 :]

        return MCSChannelJoinRequestPDU(initiator, channelID, payload)
示例#8
0
 def getPDULengthWithSocket(self, socket):
     """
     Same as getPDULength, but using a network socket.
     :type socket: socket.socket
     """
     data = socket.recv(3)
     return data, Uint16BE.unpack(data[1:])
示例#9
0
    def parseConferenceCreateResponse(
            self, stream: BytesIO) -> GCCConferenceCreateResponsePDU:
        """
        Parse ConferenceCreateResponse data into a GCCPDU
        :param stream: byte stream containing the PDU data
        """

        nodeID = Uint16BE.unpack(stream.read(2)) + 1001
        tag = per.readInteger(stream)
        result = per.readEnumeration(stream)

        userDataCount = per.readNumberOfSet(stream)
        if userDataCount != 1:
            raise ParsingError("Expected user data count to be 1, got %d" %
                               userDataCount)

        userDataType = per.readChoice(stream)
        if userDataType != 0xc0:
            raise ParsingError(
                "Expected user data type to be 0xc0 (h221NonStandard), got %d"
                % userDataType)

        key = per.readOctetStream(stream, 4)
        if key != GCCParser.H221_SERVER_KEY:
            raise ParsingError("Expected user data key to be %s, got %s" %
                               (GCCParser.H221_SERVER_KEY, key))

        payload = per.readOctetStream(stream)
        return GCCConferenceCreateResponsePDU(nodeID, tag, result, payload)
示例#10
0
 def getPDULength(self, data):
     """
     Get the length of the PDU contained in data.
     :param data: the PDU data.
     :type data: bytes
     :return: int
     """
     return Uint16BE.unpack(data[2:4])
示例#11
0
    def writeAttachUserConfirm(self, stream: BytesIO, pdu: MCSAttachUserConfirmPDU):
        """
        Encode a Attach User Confirm PDU
        :param stream: The destination stream to write into.
        :param pdu: the PDU to encode.
        """
        stream.write(per.writeEnumeration(pdu.result))

        if pdu.initiator is not None:
            stream.write(Uint16BE.pack(pdu.initiator - MCSChannelID.USERCHANNEL_BASE))
示例#12
0
    def parseChannelJoinConfirm(self, stream: BytesIO) -> MCSChannelJoinConfirmPDU:
        """
        Parse a Channel Join Confirm PDU
        :param stream: stream containing the data
        """
        result = per.readEnumeration(stream)
        data = stream.read()

        if len(data) < 4 or len(data) == 5:
            raise ParsingError("Invalid Channel Join Confirm PDU received")
        elif len(data) >= 6:
            channelID = Uint16BE.unpack(data[4 : 6])
            payload = data[6 :]
        else:
            channelID = None
            payload = b""

        initiator = Uint16BE.unpack(data[0 : 2]) + MCSChannelID.USERCHANNEL_BASE
        requested = Uint16BE.unpack(data[2 : 4])
        return MCSChannelJoinConfirmPDU(result, initiator, requested, channelID, payload)
示例#13
0
文件: tpkt.py 项目: yuraxdrumz/pyrdp
    def write(self, pdu: TPKTPDU) -> bytes:
        """
        Encode a TPKTPDU into bytes to send on the network.
        """

        stream = BytesIO()
        stream.write(Uint8.pack(pdu.header))
        stream.write(b"\x00")
        stream.write(Uint16BE.pack(len(pdu.payload) + 4))
        stream.write(pdu.payload)

        return stream.getvalue()
示例#14
0
    def writeConferenceCreateResponse(self, stream: BytesIO, pdu: GCCConferenceCreateResponsePDU):
        """
        Write a GCCConferenceCreateResponsePDU to a stream.
        :param stream: byte stream to put the ConferenceCreateResponse data in.
        :param pdu: the PDU to write.
        """

        stream.write(Uint16BE.pack(GCCParser.NODE_ID - 1001))
        stream.write(per.writeInteger(1))
        stream.write(per.writeEnumeration(0))
        stream.write(per.writeNumberOfSet(1))
        stream.write(per.writeChoice(0xc0))
        stream.write(per.writeOctetStream(GCCParser.H221_SERVER_KEY, 4))
        stream.write(per.writeOctetStream(pdu.payload))
示例#15
0
文件: tpkt.py 项目: yuraxdrumz/pyrdp
    def parse(self, data: bytes) -> TPKTPDU:
        """
        Read the byte stream and return a TPKTPDU
        """

        _version = Uint8.unpack(data[0:1])
        _padding = Uint8.unpack(data[1:2])
        length = Uint16BE.unpack(data[2:4])
        payload = data[4:length]

        if len(payload) != length - 4:
            raise ParsingError("Payload is too short for TPKT length field")

        return TPKTPDU(payload)
示例#16
0
    def parseAttachUserConfirm(self, stream: BytesIO) -> MCSAttachUserConfirmPDU:
        """
        Parse an Attach User Confirm PDU
        :param stream: stream containing the data
        """
        result = per.readEnumeration(stream)
        data = stream.read()

        initiator = None
        if len(data) == 2:
            initiator = Uint16BE.unpack(data) + MCSChannelID.USERCHANNEL_BASE
        elif len(data) > 2:
            raise ParsingError("Unexpected payload")

        return MCSAttachUserConfirmPDU(result, initiator)
示例#17
0
文件: gcc.py 项目: xianlimei/pyrdp
    def writeConferenceCreateResponse(self, stream, pdu):
        """
        Read a GCCConferenceCreateResponsePDU and put its raw data into stream
        :param stream: byte stream to put the ConferenceCreateResponse data in
        :type stream: BytesIO
        :type pdu: GCCConferenceCreateResponsePDU
        """

        stream.write(Uint16BE.pack(GCCParser.NODE_ID - 1001))
        stream.write(per.writeInteger(1))
        stream.write(per.writeEnumeration(0))
        stream.write(per.writeNumberOfSet(1))
        stream.write(per.writeChoice(0xc0))
        stream.write(per.writeOctetStream(GCCParser.H221_SERVER_KEY, 4))
        stream.write(per.writeOctetStream(pdu.payload))
示例#18
0
    def parseError(self, data, length):
        """
        Parse a Error PDU from the raw bytes
        :type data: bytes
        :param length: The length in bytes of the Error PDU.
        :return: X224ErrorPDU
        """

        if length < 4:
            raise ParsingError("Invalid X224 Error PDU length indicator: indicator = %d, expected at least 4 bytes")

        destination = Uint16BE.unpack(data[2 : 4])
        cause = Uint8.unpack(data[4])
        payload = data[5 :]

        if len(payload) != length - 4:
            raise ParsingError("Invalid X224 Error PDU payload length: expected = %d, length = %d" % (length - 4, len(payload)))

        return X224ErrorPDU(destination, cause, payload)
示例#19
0
文件: tpkt.py 项目: yuraxdrumz/pyrdp
 def getPDULength(self, data: bytes) -> int:
     """
     Get the length of the PDU contained in data.
     :param data: the PDU data.
     """
     return Uint16BE.unpack(data[2:4])
示例#20
0
 def writeLength(self, stream: BytesIO, pdu: FastPathPDU):
     length = self.calculatePDULength(pdu)
     Uint16BE.pack(length | 0x8000, stream)
示例#21
0
 def writeLength(self, stream, pdu):
     length = self.calculatePDULength(pdu)
     Uint16BE.pack(length | 0x8000, stream)