add sources
This commit is contained in:
0
rdpy/__init__.py
Normal file
0
rdpy/__init__.py
Normal file
BIN
rdpy/__init__.pyc
Normal file
BIN
rdpy/__init__.pyc
Normal file
Binary file not shown.
36
rdpy/main.py
Normal file
36
rdpy/main.py
Normal 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_())
|
||||
0
rdpy/protocols/__init__.py
Normal file
0
rdpy/protocols/__init__.py
Normal file
BIN
rdpy/protocols/__init__.pyc
Normal file
BIN
rdpy/protocols/__init__.pyc
Normal file
Binary file not shown.
0
rdpy/protocols/common/__init__.py
Normal file
0
rdpy/protocols/common/__init__.py
Normal file
BIN
rdpy/protocols/common/__init__.pyc
Normal file
BIN
rdpy/protocols/common/__init__.pyc
Normal file
Binary file not shown.
38
rdpy/protocols/common/layer.py
Normal file
38
rdpy/protocols/common/layer.py
Normal 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)
|
||||
BIN
rdpy/protocols/common/layer.pyc
Normal file
BIN
rdpy/protocols/common/layer.pyc
Normal file
Binary file not shown.
49
rdpy/protocols/common/protocolbuffer.py
Normal file
49
rdpy/protocols/common/protocolbuffer.py
Normal 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
|
||||
BIN
rdpy/protocols/common/protocolbuffer.pyc
Normal file
BIN
rdpy/protocols/common/protocolbuffer.pyc
Normal file
Binary file not shown.
70
rdpy/protocols/common/stream.py
Normal file
70
rdpy/protocols/common/stream.py
Normal 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)
|
||||
BIN
rdpy/protocols/common/stream.pyc
Normal file
BIN
rdpy/protocols/common/stream.pyc
Normal file
Binary file not shown.
0
rdpy/protocols/rdp/__init__.py
Normal file
0
rdpy/protocols/rdp/__init__.py
Normal file
BIN
rdpy/protocols/rdp/__init__.pyc
Normal file
BIN
rdpy/protocols/rdp/__init__.pyc
Normal file
Binary file not shown.
42
rdpy/protocols/rdp/tpdu.py
Normal file
42
rdpy/protocols/rdp/tpdu.py
Normal 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
BIN
rdpy/protocols/rdp/tpdu.pyc
Normal file
Binary file not shown.
69
rdpy/protocols/rdp/tpkt.py
Normal file
69
rdpy/protocols/rdp/tpkt.py
Normal 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
BIN
rdpy/protocols/rdp/tpkt.pyc
Normal file
Binary file not shown.
0
rdpy/protocols/rfb/__init__.py
Normal file
0
rdpy/protocols/rfb/__init__.py
Normal file
BIN
rdpy/protocols/rfb/__init__.pyc
Normal file
BIN
rdpy/protocols/rfb/__init__.pyc
Normal file
Binary file not shown.
25
rdpy/protocols/rfb/factory.py
Normal file
25
rdpy/protocols/rfb/factory.py
Normal 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
|
||||
BIN
rdpy/protocols/rfb/factory.pyc
Normal file
BIN
rdpy/protocols/rfb/factory.pyc
Normal file
Binary file not shown.
23
rdpy/protocols/rfb/observer.py
Normal file
23
rdpy/protocols/rfb/observer.py
Normal 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
|
||||
|
||||
BIN
rdpy/protocols/rfb/observer.pyc
Normal file
BIN
rdpy/protocols/rfb/observer.pyc
Normal file
Binary file not shown.
325
rdpy/protocols/rfb/rfb.py
Normal file
325
rdpy/protocols/rfb/rfb.py
Normal 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
BIN
rdpy/protocols/rfb/rfb.pyc
Normal file
Binary file not shown.
80
rdpy/protocols/rfb/types.py
Normal file
80
rdpy/protocols/rfb/types.py
Normal 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
|
||||
BIN
rdpy/protocols/rfb/types.pyc
Normal file
BIN
rdpy/protocols/rfb/types.pyc
Normal file
Binary file not shown.
0
rdpy/qt/__init__.py
Normal file
0
rdpy/qt/__init__.py
Normal file
BIN
rdpy/qt/__init__.pyc
Normal file
BIN
rdpy/qt/__init__.pyc
Normal file
Binary file not shown.
63
rdpy/qt/adaptor.py
Normal file
63
rdpy/qt/adaptor.py
Normal 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
BIN
rdpy/qt/adaptor.pyc
Normal file
Binary file not shown.
12
rdpy/qt/observer.py
Normal file
12
rdpy/qt/observer.py
Normal 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
BIN
rdpy/qt/observer.pyc
Normal file
Binary file not shown.
38
rdpy/qt/widget.py
Normal file
38
rdpy/qt/widget.py
Normal 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
BIN
rdpy/qt/widget.pyc
Normal file
Binary file not shown.
Reference in New Issue
Block a user