Example #1
0
 def __init__(self, sink):
     BaseEventHandler.__init__(self)
     self._fastPath = FastPathOutputParser()
     self._bitmap = BitmapParser()
     self._orders: OrdersParser = None
     self.log = logging.getLogger(__name__)
     self.sink = sink
Example #2
0
 def __init__(self, imageHandler: ImageHandler):
     BaseEventHandler.__init__(self)
     self._fastPath = FastPathOutputParser()
     self._bitmap = BitmapParser()
     self.gdi: GdiQtFrontend = None
     self._orders: OrdersParser = None
     self.log = logging.getLogger(__name__)
     self.imageHandler = imageHandler
Example #3
0
    def __init__(self, viewer, text):
        super().__init__()
        self.viewer = viewer
        self.text = text
        self.writeInCaps = False

        self.inputParser = BasicFastPathParser(ParserMode.SERVER)
        self.outputParser = BasicFastPathParser(ParserMode.CLIENT)
        self.clientInfoParser = ClientInfoParser()
        self.dataParser = SlowPathParser()
        self.clipboardParser = ClipboardParser()
        self.outputEventParser = FastPathOutputParser()
        self.clientConnectionParser = ClientConnectionParser()

        self.buffer = b""
Example #4
0
class RenderingEventHandler(BaseEventHandler):
    """Abstract class for rendering handlers."""
    def __init__(self, imageHandler: ImageHandler):
        BaseEventHandler.__init__(self)
        self._fastPath = FastPathOutputParser()
        self._bitmap = BitmapParser()
        self.gdi: GdiQtFrontend = None
        self._orders: OrdersParser = None
        self.log = logging.getLogger(__name__)
        self.imageHandler = imageHandler

    def onCapabilities(self, caps):
        if CapabilityType.CAPSTYPE_ORDER in caps:
            self.gdi = GdiQtFrontend(self.imageHandler)
            self._orders = OrdersParser(self.gdi)
            self._orders.onCapabilities(caps)

    # Generic Parsing Routines.
    def onFastPathOutput(self, event: FastPathOutputEvent):
        self.onBeginRender()
        if isinstance(event, FastPathBitmapEvent):
            parsed = self._fastPath.parseBitmapEvent(event)
            for bmp in parsed.bitmapUpdateData:
                self.onBitmap(bmp)

        elif isinstance(event, FastPathOrdersEvent):
            if self._orders is None:
                self.log.error('Received Unexpected Drawing Orders!')
                return
            self.onBeginRender()
            self._orders.parse(event)

        self.onFinishRender()

    def onSlowPathUpdate(self, pdu: UpdatePDU):
        if pdu.updateType == SlowPathUpdateType.SLOWPATH_UPDATETYPE_BITMAP:
            self.onBeginRender()

            updates = self._bitmap.parseBitmapUpdateData(pdu.updateData)
            for bmp in updates:
                self.onBitmap(bmp)

            self.onFinishRender()

    def onBitmap(self, bitmapData: BitmapUpdateData):
        image, _ = RDPBitmapToQtImage(
            bitmapData.width, bitmapData.heigth, bitmapData.bitsPerPixel,
            bitmapData.flags & BitmapFlags.BITMAP_COMPRESSION != 0,
            bitmapData.bitmapData)

        self.imageHandler.notifyImage(
            bitmapData.destLeft, bitmapData.destTop, image,
            bitmapData.destRight - bitmapData.destLeft + 1,
            bitmapData.destBottom - bitmapData.destTop + 1)

    def onBeginRender(self):
        pass

    def onFinishRender(self):
        pass
Example #5
0
    def reassembleEvent(
        self, event: FastPathOutputEvent
    ) -> Optional[Union[FastPathBitmapEvent, FastPathOutputEvent]]:
        """
        Handles FastPath event reassembly as described in
        https://msdn.microsoft.com/en-us/library/cc240622.aspx
        :param event: A potentially segmented fastpath output event
        :return: a FastPathBitmapEvent if a complete PDU has been reassembled, otherwise None. If the event is not
        fragmented, it is returned as is.
        """
        fragmentationFlag = FastPathFragmentation((event.header
                                                   & 0b00110000) >> 4)

        if fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_SINGLE:
            return event
        elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_FIRST:
            self.buffer = event.payload
        elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_NEXT:
            self.buffer += event.payload
        elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_LAST:
            self.buffer += event.payload
            event.payload = self.buffer

            return FastPathOutputParser().parseBitmapEvent(event)

        return None
Example #6
0
class PlayerMessageHandler(PlayerMessageObserver):
    """
    Class to manage the display of the RDP player when reading events.
    """
    def __init__(self, viewer, text):
        super().__init__()
        self.viewer = viewer
        self.text = text
        self.writeInCaps = False

        self.inputParser = BasicFastPathParser(ParserMode.SERVER)
        self.outputParser = BasicFastPathParser(ParserMode.CLIENT)
        self.clientInfoParser = ClientInfoParser()
        self.dataParser = SlowPathParser()
        self.clipboardParser = ClipboardParser()
        self.outputEventParser = FastPathOutputParser()
        self.clientConnectionParser = ClientConnectionParser()

        self.buffer = b""

    def onConnectionClose(self, pdu: PlayerMessagePDU):
        self.text.moveCursor(QTextCursor.End)
        self.text.insertPlainText("\n<Connection closed>")

    def onOutput(self, pdu: PlayerMessagePDU):
        pdu = self.outputParser.parse(pdu.payload)

        for event in pdu.events:
            reassembledEvent = self.reassembleEvent(event)
            if reassembledEvent is not None:
                if isinstance(reassembledEvent, FastPathOrdersEvent):
                    log.debug("Not handling orders event, not coded :)")
                elif isinstance(reassembledEvent, FastPathBitmapEvent):
                    log.debug("Handling bitmap event %(arg1)s",
                              {"arg1": type(reassembledEvent)})
                    self.onBitmap(reassembledEvent)
                else:
                    log.debug("Can't handle output event: %(arg1)s",
                              {"arg1": type(reassembledEvent)})
            else:
                log.debug("Reassembling output event...")

    def onInput(self, pdu: PlayerMessagePDU):
        pdu = self.inputParser.parse(pdu.payload)

        for event in pdu.events:
            if isinstance(event, FastPathScanCodeEvent):
                log.debug("handling %(arg1)s", {"arg1": event})
                self.onScanCode(event.scancode, not event.isReleased)
            elif isinstance(event, FastPathMouseEvent):
                self.onMousePosition(event.mouseX, event.mouseY)
            else:
                log.debug("Can't handle input event: %(arg1)s",
                          {"arg1": event})

    def onScanCode(self, code: int, isPressed: bool):
        """
        Handle scan code.
        """
        log.debug("Reading scancode %(arg1)s", {"arg1": code})

        if code in [0x2A, 0x36]:
            self.text.moveCursor(QTextCursor.End)
            self.text.insertPlainText(
                "\n<LSHIFT PRESSED>" if isPressed else "\n<LSHIFT RELEASED>")
            self.writeInCaps = not self.writeInCaps
        elif code == 0x3A and isPressed:
            self.text.moveCursor(QTextCursor.End)
            self.text.insertPlainText("\n<CAPSLOCK>")
            self.writeInCaps = not self.writeInCaps
        elif isPressed:
            char = scancodeToChar(code)
            self.text.moveCursor(QTextCursor.End)
            self.text.insertPlainText(
                char if self.writeInCaps else char.lower())

    def onMousePosition(self, x: int, y: int):
        self.viewer.setMousePosition(x, y)

    def onBitmap(self, event: FastPathBitmapEvent):
        parsedEvent = self.outputEventParser.parseBitmapEvent(event)
        for bitmapData in parsedEvent.bitmapUpdateData:
            self.handleBitmap(bitmapData)

    def handleBitmap(self, bitmapData: BitmapUpdateData):
        image = RDPBitmapToQtImage(
            bitmapData.width, bitmapData.heigth, bitmapData.bitsPerPixel,
            bitmapData.flags & BitmapFlags.BITMAP_COMPRESSION != 0,
            bitmapData.bitmapData)
        self.viewer.notifyImage(bitmapData.destLeft, bitmapData.destTop, image,
                                bitmapData.destRight - bitmapData.destLeft + 1,
                                bitmapData.destBottom - bitmapData.destTop + 1)

    def onClientInfo(self, pdu: PlayerMessagePDU):
        clientInfoPDU = self.clientInfoParser.parse(pdu.payload)
        self.text.insertPlainText(
            "USERNAME: {}\nPASSWORD: {}\nDOMAIN: {}\n".format(
                clientInfoPDU.username.replace("\0", ""),
                clientInfoPDU.password.replace("\0", ""),
                clientInfoPDU.domain.replace("\0", "")))
        self.text.insertPlainText("--------------------\n")

    def onSlowPathPDU(self, pdu: PlayerMessagePDU):
        pdu = self.dataParser.parse(pdu.payload)

        if isinstance(pdu, ConfirmActivePDU):
            self.viewer.resize(
                pdu.parsedCapabilitySets[
                    CapabilityType.CAPSTYPE_BITMAP].desktopWidth,
                pdu.parsedCapabilitySets[
                    CapabilityType.CAPSTYPE_BITMAP].desktopHeight)
        elif isinstance(
                pdu, UpdatePDU
        ) and pdu.updateType == SlowPathUpdateType.SLOWPATH_UPDATETYPE_BITMAP:
            updates = BitmapParser().parseBitmapUpdateData(pdu.updateData)
            for bitmap in updates:
                self.handleBitmap(bitmap)
        elif isinstance(pdu, InputPDU):
            for event in pdu.events:
                if isinstance(event, MouseEvent):
                    self.onMousePosition(event.x, event.y)
                elif isinstance(event, KeyboardEvent):
                    self.onScanCode(
                        event.keyCode,
                        event.flags & KeyboardFlag.KBDFLAGS_DOWN != 0)

    def onClipboardData(self, pdu: PlayerMessagePDU):
        formatDataResponsePDU: FormatDataResponsePDU = self.clipboardParser.parse(
            pdu.payload)
        self.text.moveCursor(QTextCursor.End)
        self.text.insertPlainText("\n=============\n")
        self.text.insertPlainText("CLIPBOARD DATA: {}".format(
            decodeUTF16LE(formatDataResponsePDU.requestedFormatData)))
        self.text.insertPlainText("\n=============\n")

    def onClientData(self, pdu: PlayerMessagePDU):
        """
        Prints the clientName on the screen
        """
        clientDataPDU = self.clientConnectionParser.parse(pdu.payload)
        self.text.moveCursor(QTextCursor.End)
        self.text.insertPlainText("--------------------\n")
        self.text.insertPlainText(
            f"HOST: {clientDataPDU.coreData.clientName.strip(chr(0))}\n")

    def reassembleEvent(
        self, event: FastPathOutputEvent
    ) -> Optional[Union[FastPathBitmapEvent, FastPathOutputEvent]]:
        """
        Handles FastPath event reassembly as described in
        https://msdn.microsoft.com/en-us/library/cc240622.aspx
        :param event: A potentially segmented fastpath output event
        :return: a FastPathBitmapEvent if a complete PDU has been reassembled, otherwise None. If the event is not
        fragmented, returns the original event.
        """
        fragmentationFlag = FastPathFragmentation((event.header
                                                   & 0b00110000) >> 4)
        if fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_SINGLE:
            return event
        elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_FIRST:
            self.buffer = event.payload
        elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_NEXT:
            self.buffer += event.payload
        elif fragmentationFlag == FastPathFragmentation.FASTPATH_FRAGMENT_LAST:
            self.buffer += event.payload
            event.payload = self.buffer
            return self.outputEventParser.parseBitmapEvent(event)

        return None
Example #7
0
    def onFastPathBitmap(self, event: FastPathBitmapEvent):
        parser = FastPathOutputParser()
        parsedEvent = parser.parseBitmapEvent(event)

        for bitmapData in parsedEvent.bitmapUpdateData:
            self.handleBitmap(bitmapData)