add sources

This commit is contained in:
sylvain
2013-10-12 20:30:44 +02:00
parent 9526019158
commit 2927582db1
37 changed files with 870 additions and 0 deletions

0
rdpy/__init__.py Normal file
View File

BIN
rdpy/__init__.pyc Normal file

Binary file not shown.

36
rdpy/main.py Normal file
View File

@@ -0,0 +1,36 @@
'''
Created on 4 sept. 2013
@author: sylvain
'''
import sys
from PyQt4 import QtGui
from rdpy.qt import adaptor, widget
from rdpy.protocols.rfb import rfb, factory
from rdpy.protocols.rdp import tpkt, tpdu
from twisted.internet import ssl
from OpenSSL import SSL
class ClientTLSContext(ssl.ClientContextFactory):
isClient = 1
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
if __name__ == '__main__':
#app = QtGui.QApplication(sys.argv)
#import qt4reactor
#qt4reactor.install()
#protocol = rfb.Rfb(rfb.Rfb.CLIENT)
#w = widget.QRemoteDesktop(adaptor.RfbAdaptor(protocol))
#w.resize(1000, 700)
#w.setWindowTitle('QVNCViewer')
#w.show()
from twisted.internet import reactor
#reactor.connectTCP("127.0.0.1", 5901, factory.RfbFactory(protocol))
reactor.connectTCP("192.168.122.184", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU())))
reactor.run()
sys.exit(app.exec_())

View File

BIN
rdpy/protocols/__init__.pyc Normal file

Binary file not shown.

View File

Binary file not shown.

View File

@@ -0,0 +1,38 @@
'''
Created on 5 sept. 2013
@author: sylvain
'''
class Layer(object):
'''
classdocs
'''
def __init__(self, presentation = None):
'''
Constructor
'''
self._presentation = presentation
self._transport= None
if not self._presentation is None:
self._presentation._transport = self
def connect(self):
'''
signal that the transport layer is OK
'''
if not self._presentation is None:
self._presentation.connect()
def read(self, data):
'''
signal that data is available for this layer
'''
if not self._presentation is None:
self._presentation.read(data)
def write(self, data):
'''
write using transport layer
'''
self.transport.write(data)

Binary file not shown.

View File

@@ -0,0 +1,49 @@
'''
Created on 17 aout 2013
@author: sylvain
'''
from twisted.internet import protocol
from stream import Stream
class ProtocolBuffer(protocol.Protocol):
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
#data buffer received from twisted network layer
self._buffer = ""
#len of next packet pass to next state function
self._expectedLen = 0
def dataReceived(self, data):
'''
inherit from protocol class
main event of received data
'''
self._buffer += data
while len(self._buffer) >= self._expectedLen:
expectedData = Stream(self._buffer[0:self._expectedLen])
self._buffer = self._buffer[self._expectedLen:]
self.recv(expectedData)
def expect(self, expectedLen, callback = None):
'''
newt expected len
'''
self._expectedLen = expectedLen
if callback is None:
callback = self.__class__.recv
self.recv = callback
def recv(self, data):
'''
call when expected data is receive
'''
pass

Binary file not shown.

View File

@@ -0,0 +1,70 @@
'''
Created on 12 aout 2013
@author: sylvain
'''
import struct
from StringIO import StringIO
class Stream(StringIO):
def dataLen(self):
return self.len - self.pos
def read_uint8(self):
return struct.unpack("B",self.read(1))[0]
def read_beuint16(self):
return struct.unpack(">H",self.read(2))[0]
def read_leuint16(self):
return struct.unpack("<H",self.read(2))[0]
def read_beuint24(self):
return struct.unpack(">I",'\x00'+self.read(3))[0]
def read_leuint24(self):
return struct.unpack("<I",'\x00'+self.read(3))[0]
def read_beuint32(self):
return struct.unpack(">I",self.read(4))[0]
def read_leuint32(self):
return struct.unpack("<I",self.read(4))[0]
def read_besint32(self):
return struct.unpack(">i",self.read(4))[0]
def read_lesint32(self):
return struct.unpack("<i",self.read(4))[0]
def write_uint8(self, value):
self.write(struct.pack("B", value))
def write_beuint16(self, value):
self.write(struct.pack(">H", value))
def write_leuint16(self, value):
self.write(struct.pack("<H", value))
def write_beuint24(self, value):
self.write(struct.pack(">I", value)[1:])
def write_beuint32(self, value):
self.write(struct.pack(">I", value))
def write_leuint32(self, value):
self.write(struct.pack("<I", value))
def write_besint32(self, value):
self.write(struct.pack(">i", value))
def write_lesint32(self, value):
self.write(struct.pack("<i", value))
def write_unistr(self, value):
for c in value:
self.write_uint8(ord(c))
self.write_uint8(0)
self.write_uint8(0)
self.write_uint8(0)

Binary file not shown.

View File

Binary file not shown.

View File

@@ -0,0 +1,42 @@
'''
Created on 5 sept. 2013
@author: sylvain
'''
from rdpy.protocols.common.layer import Layer
from rdpy.protocols.common.stream import Stream
class TPDU(Layer):
'''
classdocs
'''
X224_TPDU_CONNECTION_REQUEST = 0xE0
X224_TPDU_CONNECTION_CONFIRM = 0xD0
X224_TPDU_DISCONNECT_REQUEST = 0x80
X224_TPDU_DATA = 0xF0
X224_TPDU_ERROR = 0x70
def __init__(self, presentation = None):
'''
Constructor
'''
Layer.__init__(self, presentation)
def connect(self):
self.writeMessage(TPDU.X224_TPDU_CONNECTION_REQUEST)
def write(self, data):
s = Stream()
s.write_uint8(2)
s.write_uint8(TPDU.X224_TPDU_DATA)
s.write_uint8(0x80)
s.write(data.getvalue())
self._transport.write(data)
def writeMessage(self, code):
s = Stream()
s.write_uint8(6);
s.write_uint8(code);
s.write_beuint16(0);
s.write_beuint16(0);
s.write_uint8(0);
self.write(s)

BIN
rdpy/protocols/rdp/tpdu.pyc Normal file

Binary file not shown.

View File

@@ -0,0 +1,69 @@
'''
Created on 5 sept. 2013
@author: sylvain
'''
from rdpy.protocols.common.protocolbuffer import ProtocolBuffer
from rdpy.protocols.common.layer import Layer
from rdpy.protocols.common.stream import Stream
class TPKT(ProtocolBuffer, Layer):
'''
classdocs
'''
def __init__(self, presentation = None):
'''
Constructor
'''
ProtocolBuffer.__init__(self)
Layer.__init__(self, presentation)
#last packet version read from header
self._lastPacketVersion = 0
#length may be coded on more than 1 bytes
self._lastShortLength = 0
def connectionMade(self):
'''
call when transport layer connection
is made
'''
self.expect(2, self.readHeader)
self.connect()
def readHeader(self, data):
#first read packet version
self._lastPacketVersion = data.read_uint8()
if self._lastPacketVersion == 3:
data.read_uint8()
self.expect(2, self.readExtendedHeader)
else:
self._lastShortLength = data.read_uint8()
if self._lastShortLength & 0x80:
self.expect(1, self.readExtendedFastPathHeader)
return
self.expect(self._lastShortLength - 2, self.readFastPath)
def readExtendedHeader(self, data):
self.expect(data.read_beuint16() - 4, self.readData)
def readExtendedFastPathHeader(self, data):
self._lastShortLength &= ~0x80
self._lastShortLength = (self._lastShortLength << 8) + data.read_uint8()
self.expect(self._lastShortLength - 3, self.readFastPath)
def readFastPath(self, data):
pass
def readData(self, data):
self._protocol.dataReceived(data)
self.expect(2, self.readHeader)
def write(self, data):
s = Stream()
s.write_uint8(3)
s.write_uint8(0)
s.write_beuint16(data.len + 4)
s.write(data.getvalue())
self.transport.write(s.getvalue())

BIN
rdpy/protocols/rdp/tpkt.pyc Normal file

Binary file not shown.

View File

Binary file not shown.

View File

@@ -0,0 +1,25 @@
'''
Created on 22 aout 2013
@author: sylvain
'''
from twisted.internet import protocol
class RfbFactory(protocol.Factory):
'''
classdocs
'''
def __init__(self, protocol):
self._protocol = protocol
def buildProtocol(self, addr):
return self._protocol;
def startedConnecting(self, connector):
print 'Started to connect.'
def clientConnectionLost(self, connector, reason):
print 'Lost connection. Reason:', reason
def clientConnectionFailed(self, connector, reason):
print 'Connection failed. Reason:', reason

Binary file not shown.

View File

@@ -0,0 +1,23 @@
'''
Created on 4 sept. 2013
@author: sylvain
'''
class RfbObserver(object):
'''
Rfb protocol obserser
'''
def notifyFramebufferUpdate(self, width, height, x, y, pixelFormat, encoding, data):
'''
recv framebuffer update
width : width of image
height : height of image
x : x position
y : y position
pixelFormat : pixel format struct from rfb.types
encoding : encoding struct from rfb.types
data : in respect of dataFormat and pixelFormat
'''
pass

Binary file not shown.

325
rdpy/protocols/rfb/rfb.py Normal file
View File

@@ -0,0 +1,325 @@
'''
Created on 12 aout 2013
@author: sylvain
'''
from rdpy.protocols.common.stream import Stream
from rdpy.protocols.common.protocolbuffer import ProtocolBuffer
from types import PixelFormat,ProtocolVersion,SecurityType, Rectangle, Encoding
class Rfb(ProtocolBuffer):
'''
implements rfb protocol message
'''
CLIENT = 0
SERVER = 1
def __init__(self, mode):
'''
constructor
mode can be only client or server mode
'''
ProtocolBuffer.__init__(self)
#usefull for rfb protocol
self._callbackBody = None
#mode of automata
self._mode = mode
#protocol version negociated
self._version = ProtocolVersion.RFB003008
#nb security launch by server
self._securityLevel = SecurityType.INVALID
#shared framebuffer
self._sharedFlag = 0
#framebuffer width
self._width = 0
#framebuffer height
self._height = 0
#pixel format structure
self._pixelFormat = PixelFormat()
#server name
self._serverName = None
#nb rectangle
self._nbRect = 0
#current rectangle header
self._currentRect = Rectangle()
#client or server adaptor
self._observer = []
def addObserver(self, observer):
self._observer.append(observer)
def expectWithHeader(self, expectedHeaderLen, callbackBody):
'''
2nd level of waiting event
read expectedHeaderLen that contain body size
'''
self._callbackBody = callbackBody
self.expect(expectedHeaderLen, self.expectedBody)
def expectedBody(self, data):
'''
read header and expect body
'''
bodyLen = 0
if data.len == 1:
bodyLen = data.read_uint8()
elif data.len == 2:
bodyLen = data.read_beuint16()
elif data.len == 4:
bodyLen = data.read_beuint32()
else:
print "invalid header length"
return
self.expect(bodyLen, self._callbackBody)
def readProtocolVersionFormat(self, data):
if data.getvalue() == "RFB 003.003\n":
self._version = ProtocolVersion.RFB003003
return
if data.getvalue() == "RFB 003.007\n":
self._version = ProtocolVersion.RFB003007
return
if data.getvalue() == "RFB 003.008\n":
self._version = ProtocolVersion.RFB003008
return
self._version = ProtocolVersion.UNKNOWN
def writeProtocolVersionFormat(self):
s = Stream()
if self._version == ProtocolVersion.RFB003003:
s.write("RFB 003.003\n")
if self._version == ProtocolVersion.RFB003007:
s.write("RFB 003.007\n")
if self._version == ProtocolVersion.RFB003008:
s.write("RFB 003.008\n")
self.transport.write(s.getvalue())
def connectionMade(self):
'''
call when transport layer connection
is made
'''
if self._mode == Rfb.CLIENT:
self.expect(12, self.readProtocolVersion)
else:
self.writeProtocolVersionFormat()
def readProtocolVersion(self, data):
'''
read handshake packet
protocol version nego
'''
self.readProtocolVersionFormat(data)
if self._version == ProtocolVersion.UNKNOWN:
print "Unknown protocol version %s send 003.008"%data.getvalue()
#protocol version is unknow try best version we can handle
self._version = ProtocolVersion.RFB003008
#send same version of
self.writeProtocolVersionFormat()
#next state read security
if self._version == ProtocolVersion.RFB003003:
self.expect(4, self.readSecurityServer)
else:
self.expectWithHeader(1, self.readSecurityList)
def readSecurityServer(self, data):
'''
security handshake for 33 rfb version
server imposed security level
'''
self._version = data.read_beuint32()
def readSecurityList(self, data):
'''
read all security list
'''
securityList = []
while data.dataLen() > 0:
securityList.append(data.read_uint8())
#select high security level
for s in securityList:
if s in [SecurityType.NONE, SecurityType.VNC] and s > self._securityLevel:
self._securityLevel = s
break
#send back security level choosen
s = Stream()
s.write_uint8(self._securityLevel)
self.transport.write(s.getvalue())
self.expect(4, self.readSecurityResult)
def readSecurityResult(self, data):
'''
Read security result packet
'''
result = data.read_beuint32()
if result == 1:
print "Authentification failed"
if self._version == ProtocolVersion.RFB003008:
self.expectWithHeader(4, self.readSecurityFailed)
else:
print "Authentification OK"
self.writeClientInit()
def readSecurityFailed(self, data):
print "Security failed cause to %s"%data.getvalue()
def readServerInit(self, data):
'''
read server init packet
'''
self._width = data.read_beuint16()
self._height = data.read_beuint16()
serverPixelFomat = PixelFormat()
serverPixelFomat.read(data)
self.expectWithHeader(4, self.readServerName)
def readServerName(self, data):
'''
read server name from server init packet
'''
self._serverName = data.getvalue()
print "Server name %s"%self._serverName
#end of handshake
#send pixel format
self.writeSetPixelFormat(self._pixelFormat)
#write encoding
self.writeSetEncoding()
#request entire zone
self.writeFramebufferUpdateRequest(False, 0, 0, self._width, self._height)
self.expect(1, self.readServerOrder)
def readServerOrder(self, data):
'''
read order receive from server
'''
packet_type = data.read_uint8()
if packet_type == 0:
self.expect(3, self.readFrameBufferUpdateHeader)
def readFrameBufferUpdateHeader(self, data):
'''
read frame buffer update packet header
'''
#padding
data.read_uint8()
self._nbRect = data.read_beuint16();
self.expect(12, self.readRectHeader)
def readRectHeader(self, data):
'''
read rectangle header
'''
self._currentRect.X = data.read_beuint16()
self._currentRect.Y = data.read_beuint16()
self._currentRect.Width = data.read_beuint16()
self._currentRect.Height = data.read_beuint16()
self._currentRect.Encoding = data.read_besint32()
if self._currentRect.Encoding == Encoding.RAW:
self.expect(self._currentRect.Width * self._currentRect.Height * (self._pixelFormat.BitsPerPixel / 8), self.readRectBody)
def readRectBody(self, data):
'''
read body of rect
'''
for observer in self._observer:
observer.notifyFramebufferUpdate(self._currentRect.Width, self._currentRect.Height, self._currentRect.X, self._currentRect.Y, self._pixelFormat, self._currentRect.Encoding, data.getvalue())
self._nbRect = self._nbRect - 1
#if there is another rect to read
if self._nbRect == 0:
#job is finish send a request
self.writeFramebufferUpdateRequest(True, 0, 0, self._width, self._height)
self.expect(1, self.readServerOrder)
else:
self.expect(12, self.readRectHeader)
def writeClientInit(self):
'''
write client init packet
'''
s = Stream()
s.write_uint8(self._sharedFlag)
self.transport.write(s.getvalue())
self.expect(20, self.readServerInit)
def writeSetPixelFormat(self, pixelFormat):
'''
write set pixel format packet
'''
s = Stream()
#message type
s.write_uint8(0)
#padding
s.write_uint8(0)
s.write_uint8(0)
s.write_uint8(0)
pixelFormat.write(s)
self.transport.write(s.getvalue())
def writeSetEncoding(self):
'''
write set encoding packet
'''
s = Stream()
#message type
s.write_uint8(2)
#padding
s.write_uint8(0)
#nb encoding
s.write_beuint16(1)
#raw encoding
s.write_besint32(0)
self.transport.write(s.getvalue())
def writeFramebufferUpdateRequest(self, incremental, x, y, width, height):
'''
request server the specified zone
incremental means request only change before last update
'''
s = Stream()
s.write_uint8(3)
s.write_uint8(incremental)
s.write_beuint16(x)
s.write_beuint16(y)
s.write_beuint16(width)
s.write_beuint16(height)
self.transport.write(s.getvalue())
def writeKeyEvent(self, downFlag, key):
'''
write key event packet
'''
s = Stream()
s.write_uint8(4)
s.write_uint8(downFlag)
s.write_beuint16(0)
s.write_beuint32(key)
self.transport.write(s.getvalue())
def writePointerEvent(self, mask, x, y):
'''
write pointer event packet
'''
s= Stream()
s.write_uint8(5)
s.write_uint8(mask)
s.write_beuint16(x)
s.write_beuint16(y)
self.transport.write(s.getvalue())
def writeClientCutText(self, text):
'''
write client cut text event packet
'''
s = Stream()
s.write_uint8(6)
#padding
s.write_uint8(0)
s.write_uint8(0)
s.write_uint8(0)
s.write_beuint32(len(text))
s.write(text)
self.transport.write(s.getvalue())

BIN
rdpy/protocols/rfb/rfb.pyc Normal file

Binary file not shown.

View File

@@ -0,0 +1,80 @@
'''
Created on 22 aout 2013
@author: sylvain
'''
class ProtocolVersion(object):
'''
different ptotocol version
'''
UNKNOWN = 0
RFB003003 = 1
RFB003007 = 2
RFB003008 = 3
class SecurityType:
'''
security type supported by twisted remote desktop
'''
INVALID = 0
NONE = 1
VNC = 2
class PixelFormat(object):
def __init__(self):
self.BitsPerPixel = 32
self.Depth = 24
self.BigEndianFlag = False
self.TrueColorFlag = True
self.RedMax = 255
self.GreenMax = 255
self.BlueMax = 255
self.RedShift = 16
self.GreenShift = 8
self.BlueShift = 0
def read(self, data):
self.BitsPerPixel = data.read_uint8()
self.Depth = data.read_uint8()
self.BigEndianFlag = data.read_uint8()
self.TrueColorFlag = data.read_uint8()
self.RedMax = data.read_beuint16()
self.GreenMax = data.read_beuint16()
self.BlueMax = data.read_beuint16()
self.RedShift = data.read_uint8()
self.GreenShift = data.read_uint8()
self.BlueShift = data.read_uint8()
#padding
data.read(3)
def write(self, data):
data.write_uint8(self.BitsPerPixel)
data.write_uint8(self.Depth)
data.write_uint8(self.BigEndianFlag)
data.write_uint8(self.TrueColorFlag)
data.write_beuint16(self.RedMax)
data.write_beuint16(self.GreenMax)
data.write_beuint16(self.BlueMax)
data.write_uint8(self.RedShift)
data.write_uint8(self.GreenShift)
data.write_uint8(self.BlueShift)
#padding
data.write_uint8(0)
data.write_uint8(0)
data.write_uint8(0)
class Pointer:
BUTTON1 = 0x1
BUTTON2 = 0x2
BUTTON3 = 0x4
class Rectangle:
def __init__(self):
self.X = 0
self.Y = 0
self.Width = 0
self.Height = 0
self.Encoding = 0
class Encoding:
RAW = 0

Binary file not shown.

0
rdpy/qt/__init__.py Normal file
View File

BIN
rdpy/qt/__init__.pyc Normal file

Binary file not shown.

63
rdpy/qt/adaptor.py Normal file
View File

@@ -0,0 +1,63 @@
'''
Created on 4 sept. 2013
@author: sylvain
'''
from PyQt4 import QtGui
from rdpy.protocols.rfb.observer import RfbObserver
class QAdaptor(object):
'''
Adaptor for all qt
'''
def __init__(self):
self._observers = []
def addObserver(self, observer):
self._observers.append(observer)
def notifyImage(self, x, y, qimage):
for observer in self._observers:
observer.notifyImage(x, y, qimage)
def sendMouseEvent(self, e):
pass
def sendKeyEvent(self, e):
pass
class RfbAdaptor(RfbObserver, QAdaptor):
'''
classdocs
'''
def __init__(self, rfb):
QAdaptor.__init__(self)
self._rfb = rfb
self._rfb.addObserver(self)
def notifyFramebufferUpdate(self, width, height, x, y, pixelFormat, encoding, data):
'''
implement RfbAdaptor interface
'''
imageFormat = None
if pixelFormat.BitsPerPixel == 32 and pixelFormat.RedShift == 16:
imageFormat = QtGui.QImage.Format_RGB32
else:
print "Receive image in bad format"
return
image = QtGui.QImage(data, width, height, imageFormat)
self.notifyImage(x, y, image)
def sendMouseEvent(self, e):
'''
convert qt mouse event to rfb mouse event
'''
self._rfb.writePointerEvent(0, e.pos().x(), e.pos().y())
def sendKeyEvent(self, e):
'''
convert qt key press event to rfb press event
'''
self._rfb.writeKeyEvent(True, e.nativeVirtualKey())

BIN
rdpy/qt/adaptor.pyc Normal file

Binary file not shown.

12
rdpy/qt/observer.py Normal file
View File

@@ -0,0 +1,12 @@
'''
Created on 4 sept. 2013
@author: sylvain
'''
class QObserver(object):
'''
classdocs
'''
def notifyImage(self, x, y, qimage):
pass

BIN
rdpy/qt/observer.pyc Normal file

Binary file not shown.

38
rdpy/qt/widget.py Normal file
View File

@@ -0,0 +1,38 @@
'''
Created on 4 sept. 2013
@author: sylvain
'''
from PyQt4 import QtGui
from observer import QObserver
class QRemoteDesktop(QtGui.QWidget, QObserver):
def __init__(self, adaptor):
super(QRemoteDesktop, self).__init__()
self._adaptor = adaptor
self._adaptor.addObserver(self)
self._refresh = []
self.setMouseTracking(True)
def notifyImage(self, x, y, qimage):
self._refresh.append({"x" : x, "y" : y, "image" : qimage})
self.update()
def paintEvent(self, e):
if self._refresh == []:
return
qp = QtGui.QPainter()
qp.begin(self)
for image in self._refresh:
qp.drawImage(image["x"], image["y"], image["image"])
qp.end()
self._lastReceive = []
def mouseMoveEvent(self, event):
self._adaptor.sendMouseEvent(event)
def keyPressEvent(self, event):
self._adaptor.sendKeyEvent(event)

BIN
rdpy/qt/widget.pyc Normal file

Binary file not shown.