Start python3

This commit is contained in:
unknown
2020-04-14 21:56:46 +02:00
parent cef16a9f64
commit 3f56b25f46
46 changed files with 256 additions and 1146 deletions

2
.gitignore vendored
View File

@@ -7,3 +7,5 @@ README.md~
dist/*
build/*
rdpy.egg-info/*
*.pyd
.idea

View File

@@ -145,7 +145,7 @@ In a nutshell RDPY can be used as a protocol library with a twisted engine.
### Simple RDP Client
```python
from rdpy.protocol.rdp import rdp
from rdpy.core import rdp
class MyRDPFactory(rdp.ClientFactory):
@@ -201,7 +201,7 @@ reactor.run()
### Simple RDP Server
```python
from rdpy.protocol.rdp import rdp
from rdpy.core import rdp
class MyRDPFactory(rdp.ServerFactory):

View File

@@ -23,13 +23,13 @@ example of use rdpy as rdp client
import sys, os, getopt, socket
from PyQt4 import QtGui, QtCore
from PyQt5 import QtWidgets
from rdpy.ui.qt4 import RDPClientQt
from rdpy.protocol.rdp import rdp
from rdpy.core.error import RDPSecurityNegoFail
from rdpy.core import rss
from rdpy.model.error import RDPSecurityNegoFail
from rdpy.model import rss
from rdpy.core import rdp
import rdpy.core.log as log
import rdpy.model.log as log
log._LOG_LEVEL = log.Level.INFO
@@ -87,6 +87,7 @@ class RDPClientQtRecorder(RDPClientQt):
self._rssRecorder.close()
RDPClientQt.closeEvent(self, e)
class RDPClientQtFactory(rdp.ClientFactory):
"""
@summary: Factory create a RDP GUI client
@@ -211,7 +212,7 @@ def autoDetectKeyboardLayout():
return "en"
def help():
print """
print("""
Usage: rdpy-rdpclient [options] ip[:port]"
\t-u: user name
\t-p: password
@@ -222,7 +223,7 @@ def help():
\t-k: keyboard layout [en|fr] [default : en]
\t-o: optimized session (disable costly effect) [default : False]
\t-r: rss_filepath Recorded Session Scenario [default : None]
"""
""")
if __name__ == '__main__':
@@ -270,19 +271,11 @@ if __name__ == '__main__':
ip, port = args[0], "3389"
#create application
app = QtGui.QApplication(sys.argv)
#add qt4 reactor
import qt4reactor
qt4reactor.install()
app = QtWidgets.QApplication(sys.argv)
if fullscreen:
width = QtGui.QDesktopWidget().screenGeometry().width()
height = QtGui.QDesktopWidget().screenGeometry().height()
width = QtWidgets.QDesktopWidget().screenGeometry().width()
height = QtWidgets.QDesktopWidget().screenGeometry().height()
log.info("keyboard layout set to %s"%keyboardLayout)
from twisted.internet import reactor
reactor.connectTCP(ip, int(port), RDPClientQtFactory(width, height, username, password, domain, fullscreen, keyboardLayout, optimized, "nego", recodedPath))
reactor.runReturn()
app.exec_()
sys.exit(app.exec_())

View File

@@ -22,10 +22,10 @@
RDP Honey pot use Rss scenario file to simulate RDP server
"""
import sys, os, getopt, time, datetime
import sys, getopt, datetime
from rdpy.core import log, error, rss
from rdpy.protocol.rdp import rdp
from rdpy.core import log, rss
from rdpy.core import rdp
from twisted.internet import reactor
log._LOG_LEVEL = log.Level.INFO

View File

@@ -29,13 +29,12 @@ Client RDP -> | ProxyServer | ProxyClient | -> Server RDP
-----------------
"""
import sys
import os
import argparse
import time
from rdpy.core import log, error, rss
from rdpy.protocol.rdp import rdp
from rdpy.core import log, rss
from rdpy.core import rdp
from twisted.internet import reactor
log._LOG_LEVEL = log.Level.INFO

View File

@@ -24,15 +24,13 @@ take screenshot of login page
"""
import getopt
import os
import sys
from PyQt4 import QtCore, QtGui
from rdpy.protocol.rdp import rdp
from PyQt4 import QtGui
from rdpy.core import rdp
from rdpy.ui.qt4 import RDPBitmapToQtImage
import rdpy.core.log as log
from rdpy.core.error import RDPSecurityNegoFail
from twisted.internet import task
# set log level
log._LOG_LEVEL = log.Level.INFO

View File

@@ -939,9 +939,18 @@ static PyMethodDef rle_methods[] =
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
initrle(void)
static struct PyModuleDef rle =
{
(void) Py_InitModule("rle", rle_methods);
PyModuleDef_HEAD_INIT,
"rle", /* name of module */
"", /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
rle_methods
};
PyMODINIT_FUNC
PyInit_rle(void)
{
(void) PyModule_Create(&rle);
}

View File

@@ -22,11 +22,11 @@
@see: http://msdn.microsoft.com/en-us/library/cc241880.aspx
"""
from rdpy.core.type import CompositeType, CallableValue, UInt8, UInt16Le, UInt32Le, String, sizeof, FactoryType, ArrayType, Stream
from rdpy.core.error import InvalidExpectedDataException
import rdpy.core.log as log
import sec
from t125 import gcc
from rdpy.model.type import CompositeType, CallableValue, UInt8, UInt16Le, UInt32Le, String, sizeof, FactoryType, ArrayType, Stream
from rdpy.model.error import InvalidExpectedDataException
import rdpy.model.log as log
from rdpy.core import sec
from rdpy.core.t125 import gcc
from rdpy.security import rc4
from rdpy.security import rsa_wrapper as rsa

View File

@@ -27,11 +27,9 @@ import pyasn1.codec.der.encoder as der_encoder
import pyasn1.codec.der.decoder as der_decoder
import pyasn1.codec.ber.encoder as ber_encoder
from rdpy.core.type import Stream
from twisted.internet import protocol
from OpenSSL import crypto
from rdpy.model.type import Stream
from rdpy.security import x509
from rdpy.core import error
from rdpy.model import error
class NegoToken(univ.Sequence):
componentType = namedtype.NamedTypes(
@@ -175,7 +173,7 @@ def encodeDERTCredentials(domain, username, password):
return der_encoder.encode(credentials)
class CSSP(protocol.Protocol):
class CSSP:
"""
@summary: Handle CSSP connection
Proxy class for authentication

View File

@@ -23,12 +23,12 @@
"""
import hashlib, hmac, struct, datetime
import sspi
from rdpy.core.nla import sspi
import rdpy.security.pyDes as pyDes
import rdpy.security.rc4 as rc4
from rdpy.security.rsa_wrapper import random
from rdpy.core.type import CompositeType, CallableValue, String, UInt8, UInt16Le, UInt24Le, UInt32Le, sizeof, Stream
from rdpy.core import filetimes, error
from rdpy.model.type import CompositeType, CallableValue, String, UInt8, UInt16Le, UInt24Le, UInt32Le, sizeof, Stream
from rdpy.model import filetimes, error
class MajorVersion(object):
"""

View File

@@ -21,7 +21,7 @@
@summary: security service provider interface (Microsoft)
"""
from rdpy.core.error import CallPureVirtualFuntion
from rdpy.model.error import CallPureVirtualFuntion
class IAuthenticationProtocol(object):
"""

View File

@@ -16,15 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from rdpy.core.error import InvalidExpectedDataException
import rdpy.core.log as log
from rdpy.model.error import InvalidExpectedDataException
import rdpy.model.log as log
"""
Definition of structure use for capabilities nego
Use in PDU layer
"""
from rdpy.core.type import CompositeType, CallableValue, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
from rdpy.model.type import CompositeType, CallableValue, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
class CapsType(object):
"""

View File

@@ -22,10 +22,10 @@ Implement the main graphic layer
In this layer are managed all mains bitmap update orders end user inputs
"""
from rdpy.core.type import CompositeType, CallableValue, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
from rdpy.core.error import InvalidExpectedDataException
import rdpy.core.log as log
import caps, order
from rdpy.model.type import CompositeType, CallableValue, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
from rdpy.model.error import InvalidExpectedDataException
import rdpy.model.log as log
from rdpy.core.pdu import caps, order
class PDUType(object):
"""

View File

@@ -23,12 +23,13 @@ Implement the main graphic layer
In this layer are managed all mains bitmap update orders end user inputs
"""
from rdpy.core.layer import LayerAutomata
from rdpy.core.error import CallPureVirtualFuntion
from rdpy.core.type import ArrayType
import rdpy.core.log as log
import rdpy.protocol.rdp.tpkt as tpkt
import data, caps
from rdpy.model.layer import LayerAutomata
from rdpy.model.error import CallPureVirtualFuntion
from rdpy.model.type import ArrayType
import rdpy.model.log as log
from rdpy.core import tpkt
from rdpy.core.pdu import data, caps
class PDUClientListener(object):
"""

View File

@@ -21,9 +21,9 @@
GDI order structure
"""
from rdpy.core import log
from rdpy.core.error import InvalidExpectedDataException
from rdpy.core.type import CompositeType, UInt8, String, FactoryType, SInt8, SInt16Le
from rdpy.model import log
from rdpy.model.error import InvalidExpectedDataException
from rdpy.model.type import CompositeType, UInt8, String, FactoryType, SInt8, SInt16Le
class ControlFlag(object):
"""

View File

@@ -21,15 +21,19 @@
Use to manage RDP stack in twisted
"""
from rdpy.core import layer
from rdpy.core.error import CallPureVirtualFuntion, InvalidValue
import pdu.layer
import pdu.data
import pdu.caps
import rdpy.core.log as log
import tpkt, x224, sec
from t125 import mcs, gcc
from nla import cssp, ntlm
from rdpy.model import layer
from rdpy.model.error import CallPureVirtualFuntion, InvalidValue
from rdpy.core.pdu.layer import PDUClientListener, PDUServerListener
from rdpy.core.pdu import data
from rdpy.core.pdu import caps
from rdpy.core.pdu import layer as pdu
import rdpy.model.log as log
import rdpy.core.tpkt as tpkt
import rdpy.core.x224 as x224
import rdpy.core.sec as sec
from rdpy.core.t125 import mcs, gcc
from rdpy.core.nla import cssp, ntlm
class SecurityLevel(object):
"""
@@ -39,7 +43,8 @@ class SecurityLevel(object):
RDP_LEVEL_SSL = 1
RDP_LEVEL_NLA = 2
class RDPClientController(pdu.layer.PDUClientListener):
class RDPClientController(PDUClientListener):
"""
Manage RDP stack as client
"""
@@ -47,7 +52,7 @@ class RDPClientController(pdu.layer.PDUClientListener):
#list of observer
self._clientObserver = []
#PDU layer
self._pduLayer = pdu.layer.Client(self)
self._pduLayer = pdu.Client(self)
#secure layer
self._secLayer = sec.Client(self._pduLayer)
#multi channel service
@@ -365,7 +370,8 @@ class RDPClientController(pdu.layer.PDUClientListener):
"""
self._pduLayer.close()
class RDPServerController(pdu.layer.PDUServerListener):
class RDPServerController(PDUServerListener):
"""
@summary: Controller use in server side mode
"""
@@ -585,49 +591,50 @@ class ClientFactory(layer.RawLayerClientFactory):
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "buildObserver", "ClientFactory"))
class ServerFactory(layer.RawLayerServerFactory):
"""
@summary: Factory of Server RDP protocol
"""
def __init__(self, colorDepth, privateKeyFileName = None, certificateFileName = None):
"""
@param colorDepth: color depth of session
@param privateKeyFileName: file contain server private key (if none -> back to standard RDP security)
@param certficiateFileName: file that contain public key (if none -> back to standard RDP security)
"""
self._colorDepth = colorDepth
self._privateKeyFileName = privateKeyFileName
self._certificateFileName = certificateFileName
def connectionLost(self, tpktLayer, reason):
"""
@param reason: twisted reason
"""
#retrieve controller
x224Layer = tpktLayer._presentation
mcsLayer = x224Layer._presentation
secLayer = mcsLayer._channels[mcs.Channel.MCS_GLOBAL_CHANNEL]
pduLayer = secLayer._presentation
controller = pduLayer._listener
controller.onClose()
def buildRawLayer(self, addr):
"""
@summary: Function call from twisted and build rdp protocol stack
@param addr: destination address
"""
controller = RDPServerController(self._colorDepth, self._privateKeyFileName, self._certificateFileName)
self.buildObserver(controller, addr)
return controller.getProtocol()
def buildObserver(self, controller, addr):
"""
@summary: Build observer use for connection
@param controller: RDP stack controller
@param addr: destination address
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "buildObserver", "ServerFactory"))
# class ServerFactory(RawLayerServerFactory):
# """
# @summary: Factory of Server RDP protocol
# """
# def __init__(self, colorDepth, privateKeyFileName = None, certificateFileName = None):
# """
# @param colorDepth: color depth of session
# @param privateKeyFileName: file contain server private key (if none -> back to standard RDP security)
# @param certficiateFileName: file that contain public key (if none -> back to standard RDP security)
# """
# self._colorDepth = colorDepth
# self._privateKeyFileName = privateKeyFileName
# self._certificateFileName = certificateFileName
#
# def connectionLost(self, tpktLayer, reason):
# """
# @param reason: twisted reason
# """
# #retrieve controller
# x224Layer = tpktLayer._presentation
# mcsLayer = x224Layer._presentation
# secLayer = mcsLayer._channels[mcs.Channel.MCS_GLOBAL_CHANNEL]
# pduLayer = secLayer._presentation
# controller = pduLayer._listener
# controller.onClose()
#
# def buildRawLayer(self, addr):
# """
# @summary: Function call from twisted and build rdp protocol stack
# @param addr: destination address
# """
# controller = RDPServerController(self._colorDepth, self._privateKeyFileName, self._certificateFileName)
# self.buildObserver(controller, addr)
# return controller.getProtocol()
#
# def buildObserver(self, controller, addr):
# """
# @summary: Build observer use for connection
# @param controller: RDP stack controller
# @param addr: destination address
# """
# raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "buildObserver", "ServerFactory"))
#
class RDPClientObserver(object):
"""
@summary: Class use to inform all RDP event handle by RDPY

View File

@@ -21,13 +21,14 @@
RDP Standard security layer
"""
import sha, md5
import lic, tpkt
from t125 import gcc, mcs
from rdpy.core.type import CompositeType, CallableValue, Stream, UInt32Le, UInt16Le, String, sizeof, UInt8
from rdpy.core.layer import LayerAutomata, IStreamSender
from rdpy.core.error import InvalidExpectedDataException
from rdpy.core import log
from hashlib import sha1 as sha
from hashlib import md5
from rdpy.core import tpkt, lic
from rdpy.core.t125 import gcc, mcs
from rdpy.model.type import CompositeType, CallableValue, Stream, UInt32Le, UInt16Le, String, sizeof, UInt8
from rdpy.model.layer import LayerAutomata, IStreamSender
from rdpy.model.error import InvalidExpectedDataException
from rdpy.model import log
from rdpy.security import rc4
import rdpy.security.rsa_wrapper as rsa

View File

@@ -22,8 +22,8 @@ Basic Encoding Rules use in RDP.
ASN.1 standard
"""
from rdpy.core.type import UInt8, UInt16Be, UInt32Be, String
from rdpy.core.error import InvalidExpectedDataException, InvalidSize
from rdpy.model.type import UInt8, UInt16Be, UInt32Be, String
from rdpy.model.error import InvalidExpectedDataException, InvalidSize
class BerPc(object):
BER_PC_MASK = 0x20

View File

@@ -22,11 +22,11 @@ Implement GCC structure use in RDP protocol
http://msdn.microsoft.com/en-us/library/cc240508.aspx
"""
import md5
from rdpy.core.type import UInt8, UInt16Le, UInt32Le, CompositeType, CallableValue, String, Stream, sizeof, FactoryType, ArrayType
import per, mcs
from rdpy.core.error import InvalidExpectedDataException
from rdpy.core import log
from hashlib import md5
from rdpy.model.type import UInt8, UInt16Le, UInt32Le, CompositeType, CallableValue, String, Stream, sizeof, FactoryType, ArrayType
from rdpy.core.t125 import per, mcs
from rdpy.model.error import InvalidExpectedDataException
from rdpy.model import log
from rdpy.security import x509
import rdpy.security.rsa_wrapper as rsa

View File

@@ -24,13 +24,13 @@ Each channel have a particular role.
The main channel is the graphical channel.
It exist channel for file system order, audio channel, clipboard etc...
"""
from rdpy.core.layer import LayerAutomata, IStreamSender, Layer
from rdpy.core.type import sizeof, Stream, UInt8, UInt16Le, String
from rdpy.core.error import InvalidExpectedDataException, InvalidValue, InvalidSize, CallPureVirtualFuntion
from ber import writeLength
import rdpy.core.log as log
from rdpy.model.layer import LayerAutomata, IStreamSender, Layer
from rdpy.model.type import sizeof, Stream, UInt8, UInt16Le, String
from rdpy.model.error import InvalidExpectedDataException, InvalidValue, InvalidSize, CallPureVirtualFuntion
from rdpy.core.t125.ber import writeLength
import rdpy.model.log as log
import ber, gcc, per
from rdpy.core.t125 import ber, gcc, per
import rdpy.security.rsa_wrapper as rsa
class Message(object):

View File

@@ -21,8 +21,8 @@
Per encoded function
"""
from rdpy.core.type import UInt8, UInt16Be, UInt32Be, String
from rdpy.core.error import InvalidValue, InvalidExpectedDataException
from rdpy.model.type import UInt8, UInt16Be, UInt32Be, String
from rdpy.model.error import InvalidValue, InvalidExpectedDataException
def readLength(s):
"""

View File

@@ -22,9 +22,10 @@ Transport packet layer implementation
Use to build correct size packet and handle slow path and fast path mode
"""
from rdpy.core.layer import RawLayer
from rdpy.core.type import UInt8, UInt16Be, sizeof
from rdpy.core.error import CallPureVirtualFuntion
from rdpy.model.layer import RawLayer
from rdpy.model.type import UInt8, UInt16Be, sizeof
from rdpy.model.error import CallPureVirtualFuntion
class Action(object):
"""

View File

@@ -23,11 +23,11 @@ Implement transport PDU layer
This layer have main goal to negociate SSL transport
RDP basic security is supported only on client side
"""
from rdpy.core import log
from rdpy.model import log
from rdpy.core.layer import LayerAutomata, IStreamSender
from rdpy.core.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof, String
from rdpy.core.error import InvalidExpectedDataException, RDPSecurityNegoFail
from rdpy.model.layer import LayerAutomata, IStreamSender
from rdpy.model.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof, String
from rdpy.model.error import InvalidExpectedDataException, RDPSecurityNegoFail
class MessageType(object):
"""
@@ -303,38 +303,8 @@ class Server(X224Layer):
if self._selectedProtocol == Protocols.PROTOCOL_SSL:
log.debug("*" * 10 + " select SSL layer " + "*" * 10)
#_transport is TPKT and transport is TCP layer of twisted
self._transport.startTLS(ServerTLSContext(self._serverPrivateKeyFileName, self._serverCertificateFileName))
#self._transport.startTLS(ServerTLSContext(self._serverPrivateKeyFileName, self._serverCertificateFileName))
#connection is done send to presentation
self.setNextState(self.recvData)
self._presentation.connect()
#open ssl needed
from twisted.internet import ssl
from OpenSSL import SSL
class ClientTLSContext(ssl.ClientContextFactory):
"""
@summary: client context factory for open ssl
"""
def getContext(self):
context = SSL.Context(SSL.TLSv1_METHOD)
context.set_options(SSL.OP_DONT_INSERT_EMPTY_FRAGMENTS)
context.set_options(SSL.OP_TLS_BLOCK_PADDING_BUG)
return context
class ServerTLSContext(ssl.DefaultOpenSSLContextFactory):
"""
@summary: Server context factory for open ssl
@param privateKeyFileName: Name of a file containing a private key
@param certificateFileName: Name of a file containing a certificate
"""
def __init__(self, privateKeyFileName, certificateFileName):
class TPDUSSLContext(SSL.Context):
def __init__(self, method):
SSL.Context.__init__(self, method)
self.set_options(SSL.OP_DONT_INSERT_EMPTY_FRAGMENTS)
self.set_options(SSL.OP_TLS_BLOCK_PADDING_BUG)
ssl.DefaultOpenSSLContextFactory.__init__(self, privateKeyFileName, certificateFileName, SSL.SSLv23_METHOD, TPDUSSLContext)

View File

@@ -22,8 +22,9 @@ Join RDPY design with twisted design
RDPY use Layer Protocol design (like twisted)
"""
import asyncio
from rdpy.model.error import CallPureVirtualFuntion
from rdpy.core.error import CallPureVirtualFuntion
class IStreamListener(object):
"""
@@ -36,6 +37,7 @@ class IStreamListener(object):
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recv", "IStreamListener"))
class IStreamSender(object):
"""
@summary: Interface use to inform stream sender capability
@@ -47,6 +49,7 @@ class IStreamSender(object):
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "send", "IStreamSender"))
class Layer(object):
"""
@summary: A simple double linked list with presentation and transport layer
@@ -80,6 +83,7 @@ class Layer(object):
if not self._transport is None:
self._transport.close()
class LayerAutomata(Layer, IStreamListener):
"""
@summary: Layer with automata callback
@@ -103,13 +107,8 @@ class LayerAutomata(Layer, IStreamListener):
self.recv = callback
#twisted layer concept
from twisted.internet import protocol
from twisted.internet.abstract import FileDescriptor
#first that handle stream
from type import Stream
class RawLayerClientFactory(protocol.ClientFactory):
class RawLayerClientFactory(asyncio.Protocol):
"""
@summary: Abstract class for Raw layer client factory
"""
@@ -137,36 +136,37 @@ class RawLayerClientFactory(protocol.ClientFactory):
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "connectionLost", "RawLayerClientFactory"))
class RawLayerServerFactory(protocol.ServerFactory):
"""
@summary: Abstract class for Raw layer server factory
"""
def buildProtocol(self, addr):
"""
@summary: Function call from twisted
@param addr: destination address
"""
rawLayer = self.buildRawLayer(addr)
rawLayer.setFactory(self)
return rawLayer
def buildRawLayer(self, addr):
"""
@summary: Override this function to build raw layer
@param addr: destination address
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recv", "IStreamListener"))
def connectionLost(self, rawlayer, reason):
"""
@summary: Override this method to handle connection lost
@param rawlayer: rawLayer that cause connectionLost event
@param reason: twisted reason
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recv", "IStreamListener"))
class RawLayer(protocol.Protocol, LayerAutomata, IStreamSender):
# class RawLayerServerFactory(protocol.ServerFactory):
# """
# @summary: Abstract class for Raw layer server factory
# """
# def buildProtocol(self, addr):
# """
# @summary: Function call from twisted
# @param addr: destination address
# """
# rawLayer = self.buildRawLayer(addr)
# rawLayer.setFactory(self)
# return rawLayer
#
# def buildRawLayer(self, addr):
# """
# @summary: Override this function to build raw layer
# @param addr: destination address
# """
# raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recv", "IStreamListener"))
#
# def connectionLost(self, rawlayer, reason):
# """
# @summary: Override this method to handle connection lost
# @param rawlayer: rawLayer that cause connectionLost event
# @param reason: twisted reason
# """
# raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recv", "IStreamListener"))
#
#
class RawLayer(asyncio.Protocol, LayerAutomata, IStreamSender):
"""
@summary: Wait event from twisted engine
And format correct size packet

View File

@@ -44,7 +44,7 @@ def log(message):
f = open(_LOG_FILE, "a+")
f.write("%s\n"%message)
f.close()
print "[*] %s"%message
print("[*] %s"%message)
def error(message):
"""

View File

@@ -22,8 +22,8 @@ Remote Session Scenario File format
Private protocol format to save events
"""
from rdpy.core.type import CompositeType, FactoryType, UInt8, UInt16Le, UInt32Le, String, sizeof, Stream
from rdpy.core import log, error
from rdpy.model.type import CompositeType, FactoryType, UInt8, UInt16Le, UInt32Le, String, sizeof, Stream
from rdpy.model import log, error
import time
class EventType(object):

View File

@@ -26,9 +26,10 @@ We are in python!
import struct
from copy import deepcopy
from StringIO import StringIO
from rdpy.core.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion, InvalidValue
import rdpy.core.log as log
from io import BytesIO
from rdpy.model.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion, InvalidValue
import rdpy.model.log as log
def sizeof(element):
"""
@@ -852,7 +853,8 @@ def decodeUnicode(s):
i += 1
return r
class Stream(StringIO):
class Stream(BytesIO):
"""
@summary: Stream use to read all types
"""

View File

@@ -1,765 +0,0 @@
#
# Copyright (c) 2014-2015 Sylvain Peyrefitte
#
# This file is part of rdpy.
#
# rdpy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Implement Remote FrameBuffer protocol use in VNC client and server
@see: http://www.realvnc.com/docs/rfbproto.pdf
@todo: server side of protocol
@todo: more encoding rectangle
"""
from rdpy.core.layer import RawLayer, RawLayerClientFactory
from rdpy.core.type import UInt8, UInt16Be, UInt32Be, SInt32Be, String, CompositeType
from rdpy.core.error import InvalidValue, CallPureVirtualFuntion
from rdpy.security.pyDes import des
import rdpy.core.log as log
class ProtocolVersion(object):
"""
@summary: Different protocol version
"""
UNKNOWN = ""
RFB003003 = "RFB 003.003\n"
RFB003007 = "RFB 003.007\n"
RFB003008 = "RFB 003.008\n"
class SecurityType(object):
"""
@summary: Security type supported
"""
INVALID = 0
NONE = 1
VNC = 2
class Pointer(object):
"""
@summary: Mouse event code (which button)
actually in RFB specification only
three buttons are supported
"""
BUTTON1 = 0x1
BUTTON2 = 0x2
BUTTON3 = 0x4
class Encoding(object):
"""
@summary: Encoding types of FrameBuffer update
"""
RAW = 0
class ClientToServerMessages(object):
"""
@summary: Client to server messages types
"""
PIXEL_FORMAT = 0
ENCODING = 2
FRAME_BUFFER_UPDATE_REQUEST = 3
KEY_EVENT = 4
POINTER_EVENT = 5
CUT_TEXT = 6
class PixelFormat(CompositeType):
"""
@summary: Pixel format structure
"""
def __init__(self):
CompositeType.__init__(self)
self.BitsPerPixel = UInt8(32)
self.Depth = UInt8(24)
self.BigEndianFlag = UInt8(False)
self.TrueColorFlag = UInt8(True)
self.RedMax = UInt16Be(255)
self.GreenMax = UInt16Be(255)
self.BlueMax = UInt16Be(255)
self.RedShift = UInt8(16)
self.GreenShift = UInt8(8)
self.BlueShift = UInt8(0)
self.padding = (UInt16Be(), UInt8())
class ServerInit(CompositeType):
"""
@summary: Server init structure
FrameBuffer configuration
"""
def __init__(self):
CompositeType.__init__(self)
self.width = UInt16Be()
self.height = UInt16Be()
self.pixelFormat = PixelFormat()
class FrameBufferUpdateRequest(CompositeType):
"""
@summary: FrameBuffer update request send from client to server
Incremental means that server send update with a specific
order, and client must draw orders in same order
"""
def __init__(self, incremental = False, x = 0, y = 0, width = 0, height = 0):
CompositeType.__init__(self)
self.incremental = UInt8(incremental)
self.x = UInt16Be(x)
self.y = UInt16Be(y)
self.width = UInt16Be(width)
self.height = UInt16Be(height)
class Rectangle(CompositeType):
"""
@summary: Header message of update rectangle
"""
def __init__(self):
CompositeType.__init__(self)
self.x = UInt16Be()
self.y = UInt16Be()
self.width = UInt16Be()
self.height = UInt16Be()
self.encoding = SInt32Be()
class KeyEvent(CompositeType):
"""
@summary: Key event structure message
Use to send a keyboard event
"""
def __init__(self):
CompositeType.__init__(self)
self.downFlag = UInt8(False)
self.padding = UInt16Be()
self.key = UInt32Be()
class PointerEvent(CompositeType):
"""
@summary: Pointer event structure message
Use to send mouse event
"""
def __init__(self):
CompositeType.__init__(self)
self.mask = UInt8()
self.x = UInt16Be()
self.y = UInt16Be()
class ClientCutText(CompositeType):
"""
@summary: Client cut text message message
Use to simulate copy paste (ctrl-c ctrl-v) only for text
"""
def __init__(self, text = ""):
CompositeType.__init__(self)
self.padding = (UInt16Be(), UInt8())
self.size = UInt32Be(len(text))
self.message = String(text)
class ServerCutTextHeader(CompositeType):
"""
@summary: Cut text header send from server to client
"""
def __init__(self):
CompositeType.__init__(self)
self.padding = (UInt16Be(), UInt8())
self.size = UInt32Be()
class RFB(RawLayer):
"""
@summary: Implement RFB protocol
"""
def __init__(self, listener):
"""
@param listener: listener use to inform new orders
"""
RawLayer.__init__(self)
#set client listener
self._clientListener = listener
#useful for RFB protocol
self._callbackBody = None
#protocol version negotiated
self._version = String(ProtocolVersion.RFB003008)
#number security launch by server
self._securityLevel = UInt8(SecurityType.INVALID)
#shared FrameBuffer client init message
self._sharedFlag = UInt8(False)
#server init message
#which contain FrameBuffer dim and pixel format
self._serverInit = ServerInit()
#client pixel format
self._pixelFormat = PixelFormat()
#server name
self._serverName = String()
#nb rectangle
self._nbRect = 0
#current rectangle header
self._currentRect = Rectangle()
#for vnc security type
self._password = '\0' * 8
def expectWithHeader(self, expectedHeaderLen, callbackBody):
"""
2nd level of waiting event
read expectedHeaderLen that contain body size
@param expectedHeaderLen: contains the number of bytes, which body length needs to be encoded
@param callbackBody: next state use when expected date from expectedHeaderLen
are received
"""
self._callbackBody = callbackBody
self.expect(expectedHeaderLen, self.expectedBody)
def expectedBody(self, data):
"""
Read header and wait header value to call next state
@param data: Stream that length are to header length (1|2|4 bytes)
set next state to callBack body when length read from header
are received
"""
bodyLen = None
if data.len == 1:
bodyLen = UInt8()
elif data.len == 2:
bodyLen = UInt16Be()
elif data.len == 4:
bodyLen = UInt32Be()
else:
log.error("invalid header length")
return
data.readType(bodyLen)
self.expect(bodyLen.value, self._callbackBody)
def connect(self):
"""
Call when transport layer connection is made
in Client mode -> wait protocol version
"""
self.expect(12, self.recvProtocolVersion)
def readProtocolVersion(self, data):
"""
Read protocol version
@param data: Stream may contain protocol version string (ProtocolVersion)
"""
data.readType(self._version)
if not self._version.value in [ProtocolVersion.RFB003003, ProtocolVersion.RFB003007, ProtocolVersion.RFB003008]:
self._version.value = ProtocolVersion.UNKNOWN
def recvProtocolVersion(self, data):
"""
Read handshake packet
If protocol receive from client is unknown
try best version of protocol version (ProtocolVersion.RFB003008)
@param data: Stream
"""
self.readProtocolVersion(data)
if self._version.value == ProtocolVersion.UNKNOWN:
log.info("Unknown protocol version %s send 003.008"%data.getvalue())
#protocol version is unknown try best version we can handle
self._version.value = ProtocolVersion.RFB003008
#send same version of
self.send(self._version)
#next state read security
if self._version.value == ProtocolVersion.RFB003003:
self.expect(4, self.recvSecurityServer)
else:
self.expectWithHeader(1, self.recvSecurityList)
def recvSecurityServer(self, data):
"""
Security handshake for 33 RFB version
Server imposed security level
@param data: well formed packet
"""
#TODO!!!
pass
def recvSecurityList(self, data):
"""
Read security list packet send from server to client
@param data: Stream that contains well formed packet
"""
securityList = []
while data.dataLen() > 0:
securityElement = UInt8()
data.readType(securityElement)
securityList.append(securityElement)
#select high security level
for s in securityList:
if s.value in [SecurityType.NONE, SecurityType.VNC] and s > self._securityLevel:
self._securityLevel = s
break
#send back security level choosen
self.send(self._securityLevel)
if self._securityLevel.value == SecurityType.VNC:
self.expect(16, self.recvVNCChallenge)
else:
self.expect(4, self.recvSecurityResult)
def recvVNCChallenge(self, data):
"""
@summary: receive challenge in VNC authentication case
@param data: Stream that contain well formed packet
"""
key = (self._password + '\0' * 8)[:8]
newkey = []
for ki in range(len(key)):
bsrc = ord(key[ki])
btgt = 0
for i in range(8):
if bsrc & (1 << i):
btgt = btgt | (1 << 7-i)
newkey.append(chr(btgt))
algo = des(newkey)
self.send(String(algo.encrypt(data.getvalue())))
self.expect(4, self.recvSecurityResult)
def recvSecurityResult(self, data):
"""
Read security result packet
Use by server to inform connection status of client
@param data: Stream that contain well formed packet
"""
result = UInt32Be()
data.readType(result)
if result == UInt32Be(1):
log.info("Authentification failed")
if self._version.value == ProtocolVersion.RFB003008:
self.expectWithHeader(4, self.recvSecurityFailed)
else:
log.debug("Authentification OK")
self.sendClientInit()
def recvSecurityFailed(self, data):
"""
Send by server to inform reason of why it's refused client
@param data: Stream that contains well formed packet
"""
log.info("Security failed cause to %s"%data.getvalue())
def recvServerInit(self, data):
"""
Read server init packet
@param data: Stream that contains well formed packet
"""
data.readType(self._serverInit)
self.expectWithHeader(4, self.recvServerName)
def recvServerName(self, data):
"""
@summary: Read server name
@param data: Stream that contains well formed packet
"""
data.readType(self._serverName)
log.info("Server name %s"%str(self._serverName))
#end of handshake
#send pixel format
self.sendPixelFormat(self._pixelFormat)
#write encoding
self.sendSetEncoding()
#request entire zone
self.sendFramebufferUpdateRequest(False, 0, 0, self._serverInit.width.value, self._serverInit.height.value)
#now i'm ready to send event
self._clientListener.onReady()
self.expect(1, self.recvServerOrder)
def recvServerOrder(self, data):
"""
@summary: Read order receive from server
Main function for bitmap update from server to client
@param data: Stream that contains well formed packet
"""
packetType = UInt8()
data.readType(packetType)
if packetType.value == 0:
self.expect(3, self.recvFrameBufferUpdateHeader)
elif packetType.value == 2:
self._clientListener.onBell()
elif packetType.value == 3:
self.expect(7, self.recvServerCutTextHeader)
else:
log.error("Unknown message type %s"%packetType.value)
def recvFrameBufferUpdateHeader(self, data):
"""
@summary: Read frame buffer update packet header
@param data: Stream that contains well formed packet
"""
#padding
nbRect = UInt16Be()
self._nbRect = data.readType((UInt8(), nbRect))
self._nbRect = nbRect.value
self.expect(12, self.recvRectHeader)
def recvRectHeader(self, data):
"""
@summary: Read rectangle header
@param data: Stream that contains well formed packet
"""
data.readType(self._currentRect)
if self._currentRect.encoding.value == Encoding.RAW:
self.expect(self._currentRect.width.value * self._currentRect.height.value * (self._pixelFormat.BitsPerPixel.value / 8), self.recvRectBody)
def recvRectBody(self, data):
"""
@summary: Read body of rectangle update
@param data: Stream that contains well formed packet
"""
self._clientListener.recvRectangle(self._currentRect, self._pixelFormat, data.getvalue())
self._nbRect -= 1
#if there is another rect to read
if self._nbRect == 0:
#job is finish send a request
self.sendFramebufferUpdateRequest(True, 0, 0, self._serverInit.width.value, self._serverInit.height.value)
self.expect(1, self.recvServerOrder)
else:
self.expect(12, self.recvRectHeader)
def recvServerCutTextHeader(self, data):
"""
@summary: callback when expect server cut text message
@param data: Stream that contains well formed packet
"""
header = ServerCutTextHeader()
data.readType(header)
self.expect(header.size.value, self.recvServerCutTextBody)
def recvServerCutTextBody(self, data):
"""
@summary: Receive server cut text body
@param data: Stream that contains well formed packet
"""
self._clientListener.onCutText(data.getvalue())
self.expect(1, self.recvServerOrder)
def sendClientInit(self):
"""
@summary: Send client init packet
"""
self.send(self._sharedFlag)
self.expect(20, self.recvServerInit)
def sendPixelFormat(self, pixelFormat):
"""
@summary: Send pixel format structure
Very important packet that inform the image struct supported by the client
@param pixelFormat: PixelFormat struct
"""
self.send((UInt8(ClientToServerMessages.PIXEL_FORMAT), UInt16Be(), UInt8(), pixelFormat))
def sendSetEncoding(self):
"""
@summary: Send set encoding packet
Actually only RAW bitmap encoding are used
"""
self.send((UInt8(ClientToServerMessages.ENCODING), UInt8(), UInt16Be(1), SInt32Be(Encoding.RAW)))
def sendFramebufferUpdateRequest(self, incremental, x, y, width, height):
"""
@summary: Request server the specified zone
incremental means request only change before last update
"""
self.send((UInt8(ClientToServerMessages.FRAME_BUFFER_UPDATE_REQUEST), FrameBufferUpdateRequest(incremental, x, y, width, height)))
def sendKeyEvent(self, keyEvent):
"""
@summary: Write key event packet
@param keyEvent: KeyEvent struct to send
"""
self.send((UInt8(ClientToServerMessages.KEY_EVENT), keyEvent))
def sendPointerEvent(self, pointerEvent):
"""
@summary: Write pointer event packet
@param pointerEvent: PointerEvent struct use
"""
self.send((UInt8(ClientToServerMessages.POINTER_EVENT), pointerEvent))
def sendClientCutText(self, text):
"""
@summary: write client cut text event packet
"""
self.send((UInt8(ClientToServerMessages.CUT_TEXT), ClientCutText(text)))
class RFBClientListener(object):
"""
@summary: Interface use to expose event receive from RFB layer
"""
def recvRectangle(self, rectangle, pixelFormat, data):
"""
@summary: Receive rectangle order
Main update order type
@param rectangle: Rectangle type header of packet
@param pixelFormat: pixelFormat struct of current session
@param data: image data
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recvRectangle", "RFBClientListener"))
def onBell(self):
"""
@summary: receive bip from server
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onBell", "RFBClientListener"))
def onCutText(self, text):
"""
@summary: Receive cut text from server
@param text: text inner cut text event
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onCutText", "RFBClientListener"))
class RFBClientController(RFBClientListener):
"""
@summary: Class use to manage RFB order and dispatch throw observers for client side
"""
def __init__(self):
self._clientObservers = []
#rfb layer to send client orders
self._rfbLayer = RFB(self)
self._isReady = False
def getProtocol(self):
"""
@return: RFB layer build by controller
"""
return self._rfbLayer
def addClientObserver(self, observer):
"""
@summary: Add new observer for this protocol
@param observer: new observer
"""
self._clientObservers.append(observer)
observer._clientListener = self
def getWidth(self):
"""
@return: width of framebuffer
"""
return self._rfbLayer._serverInit.width.value
def getHeight(self):
"""
@return: height of framebuffer
"""
return self._rfbLayer._serverInit.height.value
def getScreen(self):
"""
@return: (width, height) of screen
"""
return (self.getWidth(), self.getHeight())
def setPassword(self, password):
"""
@summary: set password for vnc authentication type
@param password: password for session
"""
self._rfbLayer._password = password
def onReady(self):
"""
@summary: rfb stack is reday to send or receive event
"""
self._isReady = True
for observer in self._clientObservers:
observer.onReady()
def recvRectangle(self, rectangle, pixelFormat, data):
"""
@summary: Receive rectangle order
Main update order type
@param rectangle: Rectangle type header of packet
@param pixelFormat: pixelFormat struct of current session
@param data: image data
"""
for observer in self._clientObservers:
observer.onUpdate(rectangle.width.value, rectangle.height.value, rectangle.x.value, rectangle.y.value, pixelFormat, rectangle.encoding, data)
def onBell(self):
"""
@summary: biiiip event
"""
for observer in self._clientObservers:
observer.onBell()
def onCutText(self, text):
"""
@summary: receive cut text event
@param text: text in cut text event
"""
for observer in self._clientObservers:
observer.onCutText(text)
def onClose(self):
"""
@summary: handle on close events
"""
if not self._isReady:
log.debug("Close on non ready layer means authentication error")
return
for observer in self._clientObservers:
observer.onClose()
def sendKeyEvent(self, isDown, key):
"""
@summary: Send a key event throw RFB protocol
@param isDown: boolean notify if key is pressed or not (True if key is pressed)
@param key: ASCII code of key
"""
if not self._isReady:
log.info("Try to send key event on non ready layer")
return
try:
event = KeyEvent()
event.downFlag.value = isDown
event.key.value = key
self._rfbLayer.sendKeyEvent(event)
except InvalidValue:
log.debug("Try to send an invalid key event")
def sendPointerEvent(self, mask, x, y):
"""
@summary: Send a pointer event throw RFB protocol
@param mask: mask of button if button 1 and 3 are pressed then mask is 00000101
@param x: x coordinate of mouse pointer
@param y: y pointer of mouse pointer
"""
if not self._isReady:
log.info("Try to send pointer event on non ready layer")
return
try:
event = PointerEvent()
event.mask.value = mask
event.x.value = x
event.y.value = y
self._rfbLayer.sendPointerEvent(event)
except InvalidValue:
log.debug("Try to send an invalid pointer event")
def close(self):
"""
@summary: close rfb stack
"""
self._rfbLayer.close()
class ClientFactory(RawLayerClientFactory):
"""
@summary: Twisted Factory of RFB protocol
"""
def buildRawLayer(self, addr):
"""
@summary: Function call by twisted on connection
@param addr: address where client try to connect
"""
controller = RFBClientController()
self.buildObserver(controller, addr)
return controller.getProtocol()
def connectionLost(self, rfblayer, reason):
"""
@summary: Override this method to handle connection lost
@param rfblayer: rfblayer that cause connectionLost event
@param reason: twisted reason
"""
#call controller
rfblayer._clientListener.onClose()
def buildObserver(self, controller, addr):
"""
@summary: Build an RFB observer object
@param controller: controller use for rfb session
@param addr: destination
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "buildObserver", "ClientFactory"))
class RFBClientObserver(object):
"""
@summary: RFB client protocol observer
"""
def __init__(self, controller):
self._controller = controller
self._controller.addClientObserver(self)
def getController(self):
"""
@return: RFB controller use by observer
"""
return self._controller
def keyEvent(self, isPressed, key):
"""
@summary: Send a key event
@param isPressed: state of key
@param key: ASCII code of key
"""
self._controller.sendKeyEvent(isPressed, key)
def mouseEvent(self, button, x, y):
"""
@summary: Send a mouse event to RFB Layer
@param button: button number which is pressed (0,1,2,3,4,5,6,7)
@param x: x coordinate of mouse pointer
@param y: y coordinate of mouse pointer
"""
mask = 0
if button == 1:
mask = 1
elif button > 1:
mask = 1 << button - 1
self._controller.sendPointerEvent(mask, x, y)
def onReady(self):
"""
@summary: Event when network stack is ready to receive or send event
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onReady", "RFBClientObserver"))
def onClose(self):
"""
@summary: On close event
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onClose", "RFBClientObserver"))
def onUpdate(self, width, height, x, y, pixelFormat, encoding, data):
"""
@summary: Receive FrameBuffer update
@param width : width of image
@param height : height of image
@param x : x position
@param y : y position
@param pixelFormat : pixel format struct from rfb.types
@param encoding : encoding struct from rfb.types
@param data : in respect of dataFormat and pixelFormat
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onUpdate", "RFBClientObserver"))
def onCutText(self, text):
"""
@summary: event when server send cut text event
@param text: text received
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onCutText", "RFBClientObserver"))
def onBell(self):
"""
@summary: event when server send biiip
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onBell", "RFBClientObserver"))

View File

@@ -23,13 +23,12 @@ Qt specific code
QRemoteDesktop is a widget use for render in rdpy
"""
from PyQt4 import QtGui, QtCore
from rdpy.protocol.rfb.rfb import RFBClientObserver
from rdpy.protocol.rdp.rdp import RDPClientObserver
from rdpy.core.error import CallPureVirtualFuntion
from PyQt5 import QtWidgets
from rdpy.core.rdp import RDPClientObserver
from rdpy.model.error import CallPureVirtualFuntion
import sys
import rdpy.core.log as log
import rdpy.model.log as log
import rle
class QAdaptor(object):
@@ -72,112 +71,10 @@ def qtImageFormatFromRFBPixelFormat(pixelFormat):
@summary: convert RFB pixel format to QtGui.QImage format
"""
if pixelFormat.BitsPerPixel.value == 32:
return QtGui.QImage.Format_RGB32
return QtWidgets.QImage.Format_RGB32
elif pixelFormat.BitsPerPixel.value == 16:
return QtGui.QImage.Format_RGB16
return QtWidgets.QImage.Format_RGB16
class RFBClientQt(RFBClientObserver, QAdaptor):
"""
@summary: QAdaptor for specific RFB protocol stack
is to an RFB observer
"""
def __init__(self, controller):
"""
@param controller: controller for observer
@param width: width of widget
@param height: height of widget
"""
RFBClientObserver.__init__(self, controller)
self._widget = QRemoteDesktop(1024, 800, self)
def getWidget(self):
"""
@return: widget use for render
"""
return self._widget
def onUpdate(self, width, height, x, y, pixelFormat, encoding, data):
"""
@summary: Implement RFBClientObserver interface
@param width: width of new image
@param height: height of new image
@param x: x position of new image
@param y: y position of new image
@param pixelFormat: pixefFormat structure in rfb.message.PixelFormat
@param encoding: encoding type rfb.message.Encoding
@param data: image data in accordance with pixel format and encoding
"""
imageFormat = qtImageFormatFromRFBPixelFormat(pixelFormat)
if imageFormat is None:
log.error("Receive image in bad format")
return
image = QtGui.QImage(data, width, height, imageFormat)
self._widget.notifyImage(x, y, image, width, height)
def onCutText(self, text):
"""
@summary: event when server send cut text event
@param text: text received
"""
def onBell(self):
"""
@summary: event when server send biiip
"""
def onReady(self):
"""
@summary: Event when network stack is ready to receive or send event
"""
(width, height) = self._controller.getScreen()
self._widget.resize(width, height)
def sendMouseEvent(self, e, isPressed):
"""
@summary: Convert Qt mouse event to RFB mouse event
@param e: qMouseEvent
@param isPressed: event come from press or release action
"""
button = e.button()
buttonNumber = 0
if button == QtCore.Qt.LeftButton:
buttonNumber = 1
elif button == QtCore.Qt.MidButton:
buttonNumber = 2
elif button == QtCore.Qt.RightButton:
buttonNumber = 3
self.mouseEvent(buttonNumber, e.pos().x(), e.pos().y())
def sendKeyEvent(self, e, isPressed):
"""
@summary: Convert Qt key press event to RFB press event
@param e: qKeyEvent
@param isPressed: event come from press or release action
"""
self.keyEvent(isPressed, e.nativeVirtualKey())
def sendWheelEvent(self, e):
"""
@summary: Convert Qt wheel event to RFB Wheel event
@param e: QKeyEvent
@param isPressed: event come from press or release action
"""
pass
def closeEvent(self, e):
"""
@summary: Call when you want to close connection
@param: QCloseEvent
"""
self._controller.close()
def onClose(self):
"""
@summary: Call when stack is close
"""
#do something maybe a message
pass
def RDPBitmapToQtImage(width, height, bitsPerPixel, isCompress, data):
"""
@@ -195,36 +92,36 @@ def RDPBitmapToQtImage(width, height, bitsPerPixel, isCompress, data):
if isCompress:
buf = bytearray(width * height * 2)
rle.bitmap_decompress(buf, width, height, data, 2)
image = QtGui.QImage(buf, width, height, QtGui.QImage.Format_RGB555)
image = QtWidgets.QImage(buf, width, height, QtWidgets.QImage.Format_RGB555)
else:
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB555).transformed(QtGui.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
image = QtWidgets.QImage(data, width, height, QtWidgets.QImage.Format_RGB555).transformed(QtWidgets.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
elif bitsPerPixel == 16:
if isCompress:
buf = bytearray(width * height * 2)
rle.bitmap_decompress(buf, width, height, data, 2)
image = QtGui.QImage(buf, width, height, QtGui.QImage.Format_RGB16)
image = QtWidgets.QImage(buf, width, height, QtWidgets.QImage.Format_RGB16)
else:
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB16).transformed(QtGui.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
image = QtWidgets.QImage(data, width, height, QtWidgets.QImage.Format_RGB16).transformed(QtWidgets.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
elif bitsPerPixel == 24:
if isCompress:
buf = bytearray(width * height * 3)
rle.bitmap_decompress(buf, width, height, data, 3)
image = QtGui.QImage(buf, width, height, QtGui.QImage.Format_RGB888)
image = QtWidgets.QImage(buf, width, height, QtWidgets.QImage.Format_RGB888)
else:
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB888).transformed(QtGui.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
image = QtWidgets.QImage(data, width, height, QtWidgets.QImage.Format_RGB888).transformed(QtWidgets.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
elif bitsPerPixel == 32:
if isCompress:
buf = bytearray(width * height * 4)
rle.bitmap_decompress(buf, width, height, data, 4)
image = QtGui.QImage(buf, width, height, QtGui.QImage.Format_RGB32)
image = QtWidgets.QImage(buf, width, height, QtWidgets.QImage.Format_RGB32)
else:
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB32).transformed(QtGui.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
image = QtWidgets.QImage(data, width, height, QtWidgets.QImage.Format_RGB32).transformed(QtWidgets.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
else:
log.error("Receive image in bad format")
image = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32)
image = QtWidgets.QImage(width, height, QtWidgets.QImage.Format_RGB32)
return image
class RDPClientQt(RDPClientObserver, QAdaptor):
@@ -330,7 +227,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
#do something maybe a message
class QRemoteDesktop(QtGui.QWidget):
class QRemoteDesktop(QtWidgets.QWidget):
"""
@summary: Qt display widget
"""
@@ -348,7 +245,7 @@ class QRemoteDesktop(QtGui.QWidget):
#bind mouse event
self.setMouseTracking(True)
#buffer image
self._buffer = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32)
self._buffer = QtWidgets.QImage(width, height, QtWidgets.QImage.Format_RGB32)
def notifyImage(self, x, y, qimage, width, height):
"""
@@ -358,7 +255,7 @@ class QRemoteDesktop(QtGui.QWidget):
@param qimage: new QImage
"""
#fill buffer image
with QtGui.QPainter(self._buffer) as qp:
with QtWidgets.QPainter(self._buffer) as qp:
qp.drawImage(x, y, qimage, 0, 0, width, height)
#force update
self.update()
@@ -369,8 +266,8 @@ class QRemoteDesktop(QtGui.QWidget):
@param width: {int} width of widget
@param height: {int} height of widget
"""
self._buffer = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32)
QtGui.QWidget.resize(self, width, height)
self._buffer = QtWidgets.QImage(width, height, QtWidgets.QImage.Format_RGB32)
QtWidgets.QWidget.resize(self, width, height)
def paintEvent(self, e):
"""
@@ -378,7 +275,7 @@ class QRemoteDesktop(QtGui.QWidget):
@param e: QEvent
"""
#draw in widget
with QtGui.QPainter(self) as qp:
with QtWidgets.QPainter(self) as qp:
qp.drawImage(0, 0, self._buffer)
def mouseMoveEvent(self, event):

View File

@@ -4,7 +4,7 @@ import setuptools
from distutils.core import setup, Extension
setup(name='rdpy',
version='1.3.2',
version='2.0.0',
description='Remote Desktop Protocol in Python',
long_description="""
RDPY is a pure Python implementation of the Microsoft RDP (Remote Desktop Protocol) protocol (Client and Server side). RDPY is built over the event driven network engine Twisted.
@@ -16,14 +16,11 @@ setup(name='rdpy',
url='https://github.com/citronneur/rdpy',
packages=[
'rdpy',
'rdpy.core',
'rdpy.model',
'rdpy.security',
'rdpy.protocol',
'rdpy.protocol.rdp',
'rdpy.protocol.rdp.pdu',
'rdpy.protocol.rdp.nla',
'rdpy.protocol.rdp.t125',
'rdpy.protocol.rfb',
'rdpy.core.pdu',
'rdpy.core.nla',
'rdpy.core.t125',
'rdpy.ui'
],
ext_modules=[Extension('rle', ['ext/rle.c'])],
@@ -37,10 +34,9 @@ setup(name='rdpy',
'bin/rdpy-vncscreenshot.py'
],
install_requires=[
'twisted',
'pyopenssl',
'PyQt5',
'PyQt5-sip',
'service_identity',
'qt4reactor',
'rsa',
'pyasn1'
],

View File

@@ -26,9 +26,9 @@ import os, sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
import unittest
import rdpy.protocol.rdp.t125.ber as ber
import rdpy.core.t125.ber as ber
import rdpy.core.type as type
import rdpy.core.error as error
class BERTest(unittest.TestCase):
"""

View File

@@ -25,7 +25,7 @@ import os, sys
# Change path so we find rdpy
sys.path.insert(1, os.path.join(sys.path[0], '..'))
from rdpy.protocol.rdp.nla import cssp, ntlm
from rdpy.core.nla import ntlm, cssp
from rdpy.security import rc4
pubKeyHex = """

View File

@@ -26,7 +26,7 @@ import os, sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
import unittest
from rdpy.protocol.rdp import lic, sec
from rdpy.core import lic, sec
import rdpy.core.type as type
#dump of server request

View File

@@ -26,7 +26,7 @@ import os, sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
import unittest
import rdpy.protocol.rdp.t125.per as per
import rdpy.core.t125.per as per
import rdpy.core.type as type
import rdpy.core.error as error
@@ -81,7 +81,7 @@ class PERTest(unittest.TestCase):
s.writeType((per.writeLength(type.sizeof(v)), v))
s.pos = 0
self.assertTrue(per.readInteger(s) == 3, "invalid readLength for type %s"%t)
self.assertTrue(per.readInteger(s) == 3, "invalid readLength for type %s" % t)
#error case
for l in [0, 3, 5]:

View File

@@ -26,9 +26,9 @@ import os, sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
import unittest
import rdpy.protocol.rdp.tpkt as tpkt
import rdpy.core.tpkt as tpkt
import rdpy.core.type as type
import rdpy.core.error as error
class TPKTTest(unittest.TestCase):
"""

View File

@@ -26,7 +26,7 @@ import os, sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
import unittest
import rdpy.protocol.rdp.x224 as x224
import rdpy.core.x224 as x224
import rdpy.core.type as type
import rdpy.core.error as error