bug fix on server side, add log engine, change lib to core
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,7 +2,7 @@
|
|||||||
.project
|
.project
|
||||||
.pydevproject
|
.pydevproject
|
||||||
README.md~
|
README.md~
|
||||||
lib/build/*
|
rdpy/core/tmp/*
|
||||||
*.so
|
*.so
|
||||||
*.os
|
*.os
|
||||||
.sconsign.dblite
|
.sconsign.dblite
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
#
|
|
||||||
# Copyright (c) 2014 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/>.
|
|
||||||
#
|
|
||||||
|
|
||||||
import sys, os
|
|
||||||
# Change path so we find rdpy
|
|
||||||
sys.path.insert(1, os.path.join(sys.path[0], '..'))
|
|
||||||
import unittest, rdpy.tests.network.type, rdpy.tests.network.const, rdpy.tests.network.layer
|
|
||||||
|
|
||||||
def headerTest(name):
|
|
||||||
print "*"*70
|
|
||||||
print name
|
|
||||||
print "*"*70
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
headerTest("Test case rdpy.test.network.type.TypeCase")
|
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(rdpy.tests.network.type.TypeCase)
|
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
|
||||||
|
|
||||||
headerTest("Test case rdpy.test.network.const.ConstCase")
|
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(rdpy.tests.network.const.ConstCase)
|
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
|
||||||
|
|
||||||
headerTest("Test case rdpy.test.network.type.layer.LayerCase")
|
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(rdpy.tests.network.layer.LayerCase)
|
|
||||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
|
||||||
|
|
||||||
57
rdpy/base/log.py
Normal file
57
rdpy/base/log.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2014 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/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Log engine in RDPY
|
||||||
|
Actually very basic log engine
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Level(object):
|
||||||
|
"""
|
||||||
|
Level log
|
||||||
|
"""
|
||||||
|
DEBUG = 0
|
||||||
|
INFO = 1
|
||||||
|
WARNING = 2
|
||||||
|
ERROR = 3
|
||||||
|
|
||||||
|
_LOG_LEVEL = Level.DEBUG
|
||||||
|
|
||||||
|
def log(message):
|
||||||
|
print message
|
||||||
|
|
||||||
|
def error(message):
|
||||||
|
if _LOG_LEVEL > Level.ERROR:
|
||||||
|
return
|
||||||
|
log("ERROR : %s"%message)
|
||||||
|
|
||||||
|
def warning(message):
|
||||||
|
if _LOG_LEVEL > Level.WARNING:
|
||||||
|
return
|
||||||
|
log("WARNING : %s"%message)
|
||||||
|
|
||||||
|
def info(message):
|
||||||
|
if _LOG_LEVEL > Level.INFO:
|
||||||
|
return
|
||||||
|
log("INFO : %s"%message)
|
||||||
|
|
||||||
|
def debug(message):
|
||||||
|
if _LOG_LEVEL > Level.DEBUG:
|
||||||
|
return
|
||||||
|
log("DEBUG : %s"%message)
|
||||||
@@ -2,7 +2,7 @@ import os
|
|||||||
import sipconfig
|
import sipconfig
|
||||||
|
|
||||||
script_dir = os.path.dirname(os.path.realpath(Dir("#/Sconstruct").abspath))
|
script_dir = os.path.dirname(os.path.realpath(Dir("#/Sconstruct").abspath))
|
||||||
build_dir = os.path.join(script_dir, "build")
|
tmp_dir = os.path.join(script_dir, "tmp")
|
||||||
src_dir = os.path.join(script_dir, "src")
|
src_dir = os.path.join(script_dir, "src")
|
||||||
sip_dir = os.path.join(script_dir, "sip")
|
sip_dir = os.path.join(script_dir, "sip")
|
||||||
|
|
||||||
@@ -14,11 +14,11 @@ def build_sip(target, source, env):
|
|||||||
os.system(" ".join([config.sip_bin, "-c", os.path.dirname(str(target[0])), str(source[0])]))
|
os.system(" ".join([config.sip_bin, "-c", os.path.dirname(str(target[0])), str(source[0])]))
|
||||||
|
|
||||||
def build_module(name, install_dir, env):
|
def build_module(name, install_dir, env):
|
||||||
targetName = os.path.join(build_dir, name, "%s.so"%name)
|
targetName = os.path.join(tmp_dir, name, "%s.so"%name)
|
||||||
|
|
||||||
sources = [Glob(os.path.join(src_dir, name,'*.c')), os.path.join(build_dir, name, "sip%scmodule.c"%name)]
|
sources = [Glob(os.path.join(src_dir, name,'*.c')), os.path.join(tmp_dir, name, "sip%scmodule.c"%name)]
|
||||||
|
|
||||||
env.Sip(os.path.join(build_dir, name, "sip%scmodule.c"%name), os.path.join(sip_dir, "%s.sip"%name))
|
env.Sip(os.path.join(tmp_dir, name, "sip%scmodule.c"%name), os.path.join(sip_dir, "%s.sip"%name))
|
||||||
|
|
||||||
#sources.append(sip)
|
#sources.append(sip)
|
||||||
lib = env.SharedLibrary(target = targetName, source = sources, SHLIBPREFIX='')
|
lib = env.SharedLibrary(target = targetName, source = sources, SHLIBPREFIX='')
|
||||||
@@ -31,6 +31,6 @@ def build_module(name, install_dir, env):
|
|||||||
env = Environment()
|
env = Environment()
|
||||||
env.Append(BUILDERS = {'Sip' : Builder(action = build_sip)})
|
env.Append(BUILDERS = {'Sip' : Builder(action = build_sip)})
|
||||||
env.Append(CPPPATH = ["/usr/include/python2.7"]);
|
env.Append(CPPPATH = ["/usr/include/python2.7"]);
|
||||||
env.VariantDir('build', 'src', duplicate=0)
|
env.VariantDir('tmp', 'src', duplicate=0)
|
||||||
build_module("rle", os.path.join(script_dir, "..", "rdpy", "ui"), env)
|
build_module("rle", script_dir, env)
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ Join RDPY design with twisted design
|
|||||||
RDPY use Layer Protocol design (like twisted)
|
RDPY use Layer Protocol design (like twisted)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from rdpy.network.error import CallPureVirtualFuntion
|
from rdpy.base.error import CallPureVirtualFuntion
|
||||||
|
|
||||||
class LayerMode(object):
|
class LayerMode(object):
|
||||||
NONE = 0
|
NONE = 0
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ We are in python we can use that!
|
|||||||
import struct
|
import struct
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from error import InvalidValue
|
from rdpy.base.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion, InvalidValue
|
||||||
from rdpy.network.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion
|
import rdpy.base.log as log
|
||||||
|
|
||||||
def sizeof(element):
|
def sizeof(element):
|
||||||
"""
|
"""
|
||||||
@@ -432,7 +432,7 @@ class CompositeType(Type):
|
|||||||
raise InvalidSize("Impossible to read type %s : read length is too small"%(self.__class__))
|
raise InvalidSize("Impossible to read type %s : read length is too small"%(self.__class__))
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print "Error during read %s::%s"%(self.__class__, name)
|
log.error("Error during read %s::%s"%(self.__class__, name))
|
||||||
#roll back already read
|
#roll back already read
|
||||||
for tmpName in self._typeName:
|
for tmpName in self._typeName:
|
||||||
if tmpName == name:
|
if tmpName == name:
|
||||||
@@ -440,7 +440,7 @@ class CompositeType(Type):
|
|||||||
s.pos -= sizeof(self.__dict__[tmpName])
|
s.pos -= sizeof(self.__dict__[tmpName])
|
||||||
raise e
|
raise e
|
||||||
if not self._readLen is None and readLen < self._readLen.value:
|
if not self._readLen is None and readLen < self._readLen.value:
|
||||||
print "WARNING : still have correct data in packet %s, read it as padding"%self.__class__
|
log.warning("still have correct data in packet %s, read it as padding"%self.__class__)
|
||||||
s.read(self._readLen.value - readLen)
|
s.read(self._readLen.value - readLen)
|
||||||
|
|
||||||
def __write__(self, s):
|
def __write__(self, s):
|
||||||
@@ -452,7 +452,7 @@ class CompositeType(Type):
|
|||||||
try:
|
try:
|
||||||
s.writeType(self.__dict__[name])
|
s.writeType(self.__dict__[name])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print "Error during write %s::%s"%(self.__class__, name)
|
log.error("Error during write %s::%s"%(self.__class__, name))
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
def __sizeof__(self):
|
def __sizeof__(self):
|
||||||
@@ -949,16 +949,4 @@ def CheckValueOnRead(cls):
|
|||||||
if self != old:
|
if self != old:
|
||||||
raise InvalidValue("CheckValueOnRead %s != %s"%(self, old))
|
raise InvalidValue("CheckValueOnRead %s != %s"%(self, old))
|
||||||
cls.read = read
|
cls.read = read
|
||||||
return cls
|
return cls
|
||||||
|
|
||||||
def hexDump(src, length=16):
|
|
||||||
'''
|
|
||||||
print hex representation of str
|
|
||||||
@param src: string
|
|
||||||
'''
|
|
||||||
FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
|
|
||||||
for c in xrange(0, len(src), length):
|
|
||||||
chars = src[c:c+length]
|
|
||||||
hexa = ' '.join(["%02x" % ord(x) for x in chars])
|
|
||||||
printable = ''.join(["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars])
|
|
||||||
print "%04x %-*s %s" % (c, length*3, hexa, printable)
|
|
||||||
@@ -23,7 +23,7 @@ ASN.1 standard
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from rdpy.network.type import UInt8, UInt16Be, UInt32Be, String
|
from rdpy.network.type import UInt8, UInt16Be, UInt32Be, String
|
||||||
from rdpy.network.error import InvalidExpectedDataException, InvalidSize
|
from rdpy.base.error import InvalidExpectedDataException, InvalidSize
|
||||||
|
|
||||||
class BerPc(object):
|
class BerPc(object):
|
||||||
BER_PC_MASK = 0x20
|
BER_PC_MASK = 0x20
|
||||||
|
|||||||
@@ -16,7 +16,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
from rdpy.network.error import InvalidExpectedDataException
|
from rdpy.base.error import InvalidExpectedDataException
|
||||||
|
import rdpy.base.log as log
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Definition of structure use for capabilities nego
|
Definition of structure use for capabilities nego
|
||||||
@@ -237,7 +238,7 @@ class Capability(CompositeType):
|
|||||||
for c in [GeneralCapability, BitmapCapability, OrderCapability, BitmapCacheCapability, PointerCapability, InputCapability, BrushCapability, GlyphCapability, OffscreenBitmapCacheCapability, VirtualChannelCapability, SoundCapability, ControlCapability, WindowActivationCapability, FontCapability, ColorCacheCapability, ShareCapability]:
|
for c in [GeneralCapability, BitmapCapability, OrderCapability, BitmapCacheCapability, PointerCapability, InputCapability, BrushCapability, GlyphCapability, OffscreenBitmapCacheCapability, VirtualChannelCapability, SoundCapability, ControlCapability, WindowActivationCapability, FontCapability, ColorCacheCapability, ShareCapability]:
|
||||||
if self.capabilitySetType.value == c._TYPE_:
|
if self.capabilitySetType.value == c._TYPE_:
|
||||||
return c(readLen = self.lengthCapability - 4)
|
return c(readLen = self.lengthCapability - 4)
|
||||||
print "WARNING : unknown Capability type : %s"%hex(self.capabilitySetType.value)
|
log.debug("unknown Capability type : %s"%hex(self.capabilitySetType.value))
|
||||||
#read entire packet
|
#read entire packet
|
||||||
return String(readLen = self.lengthCapability - 4)
|
return String(readLen = self.lengthCapability - 4)
|
||||||
|
|
||||||
|
|||||||
@@ -23,8 +23,9 @@ http://msdn.microsoft.com/en-us/library/cc240508.aspx
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from rdpy.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, Stream, sizeof, FactoryType, ArrayType
|
from rdpy.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, Stream, sizeof, FactoryType, ArrayType
|
||||||
import per
|
import per, mcs
|
||||||
from rdpy.network.error import InvalidExpectedDataException
|
from rdpy.base.error import InvalidExpectedDataException
|
||||||
|
import rdpy.base.log as log
|
||||||
|
|
||||||
t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 )
|
t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 )
|
||||||
|
|
||||||
@@ -204,7 +205,7 @@ class DataBlock(CompositeType):
|
|||||||
for c in [ClientCoreData, ClientSecurityData, ClientNetworkData, ServerCoreData, ServerNetworkData, ServerSecurityData]:
|
for c in [ClientCoreData, ClientSecurityData, ClientNetworkData, ServerCoreData, ServerNetworkData, ServerSecurityData]:
|
||||||
if self.type.value == c._TYPE_:
|
if self.type.value == c._TYPE_:
|
||||||
return c(readLen = self.length - 4)
|
return c(readLen = self.length - 4)
|
||||||
print "WARNING : unknown GCC block type : %s"%hex(self.type.value)
|
log.debug("unknown GCC block type : %s"%hex(self.type.value))
|
||||||
#read entire packet
|
#read entire packet
|
||||||
return String(readLen = self.length - 4)
|
return String(readLen = self.length - 4)
|
||||||
|
|
||||||
@@ -285,8 +286,7 @@ class ServerSecurityData(CompositeType):
|
|||||||
def __init__(self, readLen = None):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self, readLen = readLen)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.encryptionMethod = UInt32Le()
|
self.encryptionMethod = UInt32Le()
|
||||||
self.encryptionLevel = UInt32Le()
|
self.encryptionLevel = UInt32Le()
|
||||||
|
|
||||||
|
|
||||||
class ChannelDef(CompositeType):
|
class ChannelDef(CompositeType):
|
||||||
"""
|
"""
|
||||||
@@ -310,7 +310,7 @@ class ClientNetworkData(CompositeType):
|
|||||||
|
|
||||||
def __init__(self, readLen = None):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self, readLen = readLen)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.channelCount = UInt32Le()
|
self.channelCount = UInt32Le(lambda:len(self.channelDefArray._array))
|
||||||
self.channelDefArray = ArrayType(ChannelDef, readLen = self.channelCount)
|
self.channelDefArray = ArrayType(ChannelDef, readLen = self.channelCount)
|
||||||
|
|
||||||
class ServerNetworkData(CompositeType):
|
class ServerNetworkData(CompositeType):
|
||||||
@@ -323,7 +323,7 @@ class ServerNetworkData(CompositeType):
|
|||||||
|
|
||||||
def __init__(self, readLen = None):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self, readLen = readLen)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.MCSChannelId = UInt16Le()
|
self.MCSChannelId = UInt16Le(mcs.Channel.MCS_GLOBAL_CHANNEL)
|
||||||
self.channelCount = UInt16Le(lambda:len(self.channelIdArray._array))
|
self.channelCount = UInt16Le(lambda:len(self.channelIdArray._array))
|
||||||
self.channelIdArray = ArrayType(UInt16Le, readLen = self.channelCount)
|
self.channelIdArray = ArrayType(UInt16Le, readLen = self.channelCount)
|
||||||
self.pad = UInt16Le(conditional = lambda:((self.channelCount.value % 2) == 1))
|
self.pad = UInt16Le(conditional = lambda:((self.channelCount.value % 2) == 1))
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ RDP extended license
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from rdpy.network.type import CompositeType, UInt8, UInt16Le, UInt32Le, String, sizeof, FactoryType, ArrayType
|
from rdpy.network.type import CompositeType, UInt8, UInt16Le, UInt32Le, String, sizeof, FactoryType, ArrayType
|
||||||
from rdpy.network.error import InvalidExpectedDataException
|
from rdpy.base.error import InvalidExpectedDataException
|
||||||
|
import rdpy.base.log as log
|
||||||
|
|
||||||
class MessageType(object):
|
class MessageType(object):
|
||||||
"""
|
"""
|
||||||
@@ -193,7 +194,7 @@ class LicPacket(CompositeType):
|
|||||||
for c in [LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest]:
|
for c in [LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest]:
|
||||||
if self.bMsgtype.value == c._MESSAGE_TYPE_:
|
if self.bMsgtype.value == c._MESSAGE_TYPE_:
|
||||||
return c()
|
return c()
|
||||||
print "WARNING : unknown license message : %s"%self.bMsgtype.value
|
log.debug("unknown license message : %s"%self.bMsgtype.value)
|
||||||
return String()
|
return String()
|
||||||
|
|
||||||
if message is None:
|
if message is None:
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ It exist channel for file system order, audio channel, clipboard etc...
|
|||||||
"""
|
"""
|
||||||
from rdpy.network.layer import LayerAutomata, StreamSender, Layer, LayerMode
|
from rdpy.network.layer import LayerAutomata, StreamSender, Layer, LayerMode
|
||||||
from rdpy.network.type import sizeof, Stream, UInt8, UInt16Le
|
from rdpy.network.type import sizeof, Stream, UInt8, UInt16Le
|
||||||
from rdpy.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
from rdpy.base.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
||||||
from rdpy.protocol.rdp.ber import writeLength
|
from rdpy.protocol.rdp.ber import writeLength
|
||||||
|
import rdpy.base.log as log
|
||||||
|
|
||||||
import ber, gcc, per
|
import ber, gcc, per
|
||||||
|
|
||||||
@@ -115,10 +116,11 @@ class MCS(LayerAutomata):
|
|||||||
return self._mcs._serverSettings
|
return self._mcs._serverSettings
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, mode, presentation):
|
def __init__(self, mode, presentation, virtualChannels = []):
|
||||||
"""
|
"""
|
||||||
@param mode: mode of MCS layer
|
@param mode: mode of MCS layer
|
||||||
@param presentation: presentation layer
|
@param presentation: presentation layer
|
||||||
|
@param virtualChannels: list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
||||||
"""
|
"""
|
||||||
LayerAutomata.__init__(self, mode, presentation)
|
LayerAutomata.__init__(self, mode, presentation)
|
||||||
self._clientSettings = gcc.clientSettings()
|
self._clientSettings = gcc.clientSettings()
|
||||||
@@ -126,7 +128,13 @@ class MCS(LayerAutomata):
|
|||||||
#default user Id
|
#default user Id
|
||||||
self._userId = 1 + Channel.MCS_USERCHANNEL_BASE
|
self._userId = 1 + Channel.MCS_USERCHANNEL_BASE
|
||||||
#list of channel use in this layer and connection state
|
#list of channel use in this layer and connection state
|
||||||
self._channelIds = {Channel.MCS_GLOBAL_CHANNEL: presentation}
|
self._channels = {Channel.MCS_GLOBAL_CHANNEL: presentation}
|
||||||
|
#virtual channels
|
||||||
|
self._virtualChannels = virtualChannels
|
||||||
|
#nb join and confirm channel
|
||||||
|
self._nbJoinAndConfirmChannel = 0
|
||||||
|
self._isGlobalChannelRequested = False
|
||||||
|
self._isUserChannelRequested = False
|
||||||
#use to record already requested channel
|
#use to record already requested channel
|
||||||
self._channelIdsRequested = {}
|
self._channelIdsRequested = {}
|
||||||
|
|
||||||
@@ -137,7 +145,12 @@ class MCS(LayerAutomata):
|
|||||||
"""
|
"""
|
||||||
if self._mode == LayerMode.CLIENT:
|
if self._mode == LayerMode.CLIENT:
|
||||||
self._clientSettings.getBlock(gcc.MessageType.CS_CORE).serverSelectedProtocol.value = self._transport._selectedProtocol
|
self._clientSettings.getBlock(gcc.MessageType.CS_CORE).serverSelectedProtocol.value = self._transport._selectedProtocol
|
||||||
|
#ask for virtual channel
|
||||||
|
self._clientSettings.getBlock(gcc.MessageType.CS_NET).channelDefArray._array = [x for (x, _) in self._virtualChannels]
|
||||||
|
#send connect initial
|
||||||
self.sendConnectInitial()
|
self.sendConnectInitial()
|
||||||
|
#next wait response
|
||||||
|
self.setNextState(self.recvConnectResponse)
|
||||||
else:
|
else:
|
||||||
self._serverSettings.getBlock(gcc.MessageType.SC_CORE).clientRequestedProtocol.value = self._transport._requestedProtocol
|
self._serverSettings.getBlock(gcc.MessageType.SC_CORE).clientRequestedProtocol.value = self._transport._requestedProtocol
|
||||||
self.setNextState(self.recvConnectInitial)
|
self.setNextState(self.recvConnectInitial)
|
||||||
@@ -147,21 +160,41 @@ class MCS(LayerAutomata):
|
|||||||
Send sendChannelJoinRequest message on next disconnect channel
|
Send sendChannelJoinRequest message on next disconnect channel
|
||||||
client automata function
|
client automata function
|
||||||
"""
|
"""
|
||||||
for (channelId, layer) in self._channelIds.iteritems():
|
self.setNextState(self.recvChannelJoinConfirm)
|
||||||
#for each disconnect channel send a request
|
#global channel
|
||||||
if not self._channelIdsRequested.has_key(channelId):
|
if not self._isGlobalChannelRequested:
|
||||||
self.sendChannelJoinRequest(channelId)
|
self.sendChannelJoinRequest(Channel.MCS_GLOBAL_CHANNEL)
|
||||||
self.setNextState(self.recvChannelJoinConfirm)
|
self._isGlobalChannelRequested = True
|
||||||
return
|
return
|
||||||
|
|
||||||
|
#user channel
|
||||||
|
if not self._isUserChannelRequested:
|
||||||
|
self.sendChannelJoinRequest(self._userId)
|
||||||
|
self._isUserChannelRequested = True
|
||||||
|
return
|
||||||
|
|
||||||
|
#static virtual channel
|
||||||
|
if self._nbJoinAndConfirmChannel < self._serverSettings.getBlock(gcc.MessageType.SC_NET).channelCount.value:
|
||||||
|
channelId = self._serverSettings.getBlock(gcc.MessageType.SC_NET).channelIdArray._array[self._nbJoinAndConfirmChannel]
|
||||||
|
self._nbJoinAndConfirmChannel += 1
|
||||||
|
self.sendChannelJoinRequest(channelId)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.allChannelConnected()
|
||||||
|
|
||||||
|
def allChannelConnected(self):
|
||||||
|
"""
|
||||||
|
All channels are connected to MCS layer
|
||||||
|
Send connect to upper channel
|
||||||
|
And prepare MCS layer to receive data
|
||||||
|
"""
|
||||||
#connection is done
|
#connection is done
|
||||||
self.setNextState(self.recvData)
|
self.setNextState(self.recvData)
|
||||||
#try connection on all requested channel
|
#try connection on all requested channel
|
||||||
for (channelId, layer) in self._channelIds.iteritems():
|
for (channelId, layer) in self._channels.iteritems():
|
||||||
if self._channelIdsRequested[channelId] and not layer is None:
|
#use proxy for each channel
|
||||||
#use proxy for each channel
|
layer._transport = MCS.MCSProxySender(self, channelId)
|
||||||
layer._transport = MCS.MCSProxySender(self, channelId)
|
layer.connect()
|
||||||
layer.connect()
|
|
||||||
|
|
||||||
def sendConnectInitial(self):
|
def sendConnectInitial(self):
|
||||||
"""
|
"""
|
||||||
@@ -178,8 +211,6 @@ class MCS(LayerAutomata):
|
|||||||
self.writeDomainParams(0xffff, 0xfc17, 0xffff, 0xffff),
|
self.writeDomainParams(0xffff, 0xfc17, 0xffff, 0xffff),
|
||||||
ber.writeOctetstring(ccReqStream.getvalue()))
|
ber.writeOctetstring(ccReqStream.getvalue()))
|
||||||
self._transport.send((ber.writeApplicationTag(Message.MCS_TYPE_CONNECT_INITIAL, sizeof(tmp)), tmp))
|
self._transport.send((ber.writeApplicationTag(Message.MCS_TYPE_CONNECT_INITIAL, sizeof(tmp)), tmp))
|
||||||
#we must receive a connect response
|
|
||||||
self.setNextState(self.recvConnectResponse)
|
|
||||||
|
|
||||||
def sendConnectResponse(self):
|
def sendConnectResponse(self):
|
||||||
"""
|
"""
|
||||||
@@ -194,8 +225,6 @@ class MCS(LayerAutomata):
|
|||||||
ber.writeOctetstring(ccReqStream.getvalue()))
|
ber.writeOctetstring(ccReqStream.getvalue()))
|
||||||
self._transport.send((ber.writeApplicationTag(Message.MCS_TYPE_CONNECT_RESPONSE, sizeof(tmp)), tmp))
|
self._transport.send((ber.writeApplicationTag(Message.MCS_TYPE_CONNECT_RESPONSE, sizeof(tmp)), tmp))
|
||||||
|
|
||||||
self.setNextState(self.recvErectDomainRequest)
|
|
||||||
|
|
||||||
def sendErectDomainRequest(self):
|
def sendErectDomainRequest(self):
|
||||||
"""
|
"""
|
||||||
Send a formated erect domain request for RDP connection
|
Send a formated erect domain request for RDP connection
|
||||||
@@ -217,7 +246,7 @@ class MCS(LayerAutomata):
|
|||||||
Send attach user confirm
|
Send attach user confirm
|
||||||
server automata function
|
server automata function
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.ATTACH_USER_CONFIRM)),
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.ATTACH_USER_CONFIRM), 2),
|
||||||
per.writeEnumerates(0),
|
per.writeEnumerates(0),
|
||||||
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE)))
|
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE)))
|
||||||
|
|
||||||
@@ -237,7 +266,7 @@ class MCS(LayerAutomata):
|
|||||||
@param channelId: id of channel
|
@param channelId: id of channel
|
||||||
@param confirm: connection state
|
@param confirm: connection state
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_CONFIRM)),
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_CONFIRM), 2),
|
||||||
per.writeEnumerates(int(confirm)),
|
per.writeEnumerates(int(confirm)),
|
||||||
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
|
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
|
||||||
per.writeInteger16(channelId),
|
per.writeInteger16(channelId),
|
||||||
@@ -276,6 +305,7 @@ class MCS(LayerAutomata):
|
|||||||
self._serverSettings.getBlock(gcc.MessageType.SC_NET).channelIdArray._array = [UInt16Le(x + Channel.MCS_GLOBAL_CHANNEL) for x in range(1, len(self._clientSettings.getBlock(gcc.MessageType.CS_NET).channelDefArray._array) + 1)]
|
self._serverSettings.getBlock(gcc.MessageType.SC_NET).channelIdArray._array = [UInt16Le(x + Channel.MCS_GLOBAL_CHANNEL) for x in range(1, len(self._clientSettings.getBlock(gcc.MessageType.CS_NET).channelDefArray._array) + 1)]
|
||||||
|
|
||||||
self.sendConnectResponse()
|
self.sendConnectResponse()
|
||||||
|
self.setNextState(self.recvErectDomainRequest)
|
||||||
|
|
||||||
def recvConnectResponse(self, data):
|
def recvConnectResponse(self, data):
|
||||||
"""
|
"""
|
||||||
@@ -350,10 +380,6 @@ class MCS(LayerAutomata):
|
|||||||
|
|
||||||
self._userId = per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE)
|
self._userId = per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE)
|
||||||
|
|
||||||
#build channel list because we have user id
|
|
||||||
#add default channel + channels accepted by GCC connection sequence
|
|
||||||
self._channelIds[self._userId] = None
|
|
||||||
|
|
||||||
self.connectNextChannel()
|
self.connectNextChannel()
|
||||||
|
|
||||||
def recvChannelJoinRequest(self, data):
|
def recvChannelJoinRequest(self, data):
|
||||||
@@ -374,7 +400,12 @@ class MCS(LayerAutomata):
|
|||||||
raise InvalidExpectedDataException("Invalid MCS User Id")
|
raise InvalidExpectedDataException("Invalid MCS User Id")
|
||||||
|
|
||||||
channelId = per.readInteger16(data)
|
channelId = per.readInteger16(data)
|
||||||
self.sendChannelJoinConfirm(channelId, channelId in self._channelIds.keys() or channelId == self._userId)
|
#TODO check if it's a virtual channel too
|
||||||
|
#actually algo support virtual channel but not RDPY
|
||||||
|
self.sendChannelJoinConfirm(channelId, channelId in self._channels.keys() or channelId == self._userId)
|
||||||
|
self._nbJoinAndConfirmChannel += 1
|
||||||
|
if self._nbJoinAndConfirmChannel == self._serverSettings.getBlock(gcc.MessageType.SC_NET).channelCount.value + 2:
|
||||||
|
self.allChannelConnected()
|
||||||
|
|
||||||
def recvChannelJoinConfirm(self, data):
|
def recvChannelJoinConfirm(self, data):
|
||||||
"""
|
"""
|
||||||
@@ -395,8 +426,16 @@ class MCS(LayerAutomata):
|
|||||||
raise InvalidExpectedDataException("Invalid MCS User Id")
|
raise InvalidExpectedDataException("Invalid MCS User Id")
|
||||||
|
|
||||||
channelId = per.readInteger16(data)
|
channelId = per.readInteger16(data)
|
||||||
#save state of channel
|
#must confirm global channel and user channel
|
||||||
self._channelIdsRequested[channelId] = (confirm == 0)
|
if (confirm != 0) and (channelId == Channel.MCS_GLOBAL_CHANNEL or channelId == self._userId):
|
||||||
|
raise InvalidExpectedDataException("Server must confirm static channel")
|
||||||
|
|
||||||
|
if confirm ==0:
|
||||||
|
serverNet = self._serverSettings.getBlock(gcc.MessageType.SC_NET)
|
||||||
|
for i in range(0, serverNet.channelCount.value):
|
||||||
|
if channelId == serverNet.channelIdArray._array[i].value:
|
||||||
|
self._channels[channelId] = self._virtualChannels[i][1]
|
||||||
|
|
||||||
self.connectNextChannel()
|
self.connectNextChannel()
|
||||||
|
|
||||||
def recvData(self, data):
|
def recvData(self, data):
|
||||||
@@ -408,7 +447,7 @@ class MCS(LayerAutomata):
|
|||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
|
|
||||||
if self.readMCSPDUHeader(opcode.value, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
|
if self.readMCSPDUHeader(opcode.value, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
|
||||||
print "INFO : MCS DISCONNECT_PROVIDER_ULTIMATUM"
|
log.info("MCS DISCONNECT_PROVIDER_ULTIMATUM")
|
||||||
self._transport.close()
|
self._transport.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -424,16 +463,11 @@ class MCS(LayerAutomata):
|
|||||||
per.readLength(data)
|
per.readLength(data)
|
||||||
|
|
||||||
#channel id doesn't match a requested layer
|
#channel id doesn't match a requested layer
|
||||||
if not self._channelIdsRequested.has_key(channelId):
|
if not self._channels.has_key(channelId):
|
||||||
print "ERROR : receive data for an unrequested layer"
|
log.error("receive data for an unconnected layer")
|
||||||
return
|
return
|
||||||
|
|
||||||
#channel id math an unconnected layer
|
self._channels[channelId].recv(data)
|
||||||
if not self._channelIdsRequested[channelId]:
|
|
||||||
print "ERROR : receive data for an unconnected layer"
|
|
||||||
return
|
|
||||||
|
|
||||||
self._channelIds[channelId].recv(data)
|
|
||||||
|
|
||||||
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
|
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ In this layer are managed all mains bitmap update orders end user inputs
|
|||||||
|
|
||||||
from rdpy.network.layer import LayerAutomata, LayerMode
|
from rdpy.network.layer import LayerAutomata, LayerMode
|
||||||
from rdpy.network.type import CompositeType, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
|
from rdpy.network.type import CompositeType, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
|
||||||
from rdpy.network.error import InvalidExpectedDataException, CallPureVirtualFuntion, InvalidType
|
from rdpy.base.error import InvalidExpectedDataException, CallPureVirtualFuntion, InvalidType
|
||||||
|
import rdpy.base.log as log
|
||||||
import gcc, lic, caps, tpkt
|
import gcc, lic, caps, tpkt
|
||||||
|
|
||||||
class SecurityFlag(object):
|
class SecurityFlag(object):
|
||||||
@@ -562,7 +562,7 @@ class PDU(CompositeType):
|
|||||||
for c in [DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU]:
|
for c in [DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU]:
|
||||||
if self.shareControlHeader.pduType.value == c._PDUTYPE_:
|
if self.shareControlHeader.pduType.value == c._PDUTYPE_:
|
||||||
return c()
|
return c()
|
||||||
print "WARNING : unknown PDU type : %s"%hex(self.shareControlHeader.pduType.value)
|
log.debug("unknown PDU type : %s"%hex(self.shareControlHeader.pduType.value))
|
||||||
#read entire packet
|
#read entire packet
|
||||||
return String()
|
return String()
|
||||||
|
|
||||||
@@ -643,7 +643,7 @@ class DataPDU(CompositeType):
|
|||||||
for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU]:
|
for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU]:
|
||||||
if self.shareDataHeader.pduType2.value == c._PDUTYPE2_:
|
if self.shareDataHeader.pduType2.value == c._PDUTYPE2_:
|
||||||
return c()
|
return c()
|
||||||
print "WARNING : unknown PDU data type : %s"%hex(self.shareDataHeader.pduType2.value)
|
log.debug("unknown PDU data type : %s"%hex(self.shareDataHeader.pduType2.value))
|
||||||
return String()
|
return String()
|
||||||
|
|
||||||
if pduData is None:
|
if pduData is None:
|
||||||
@@ -936,7 +936,7 @@ class SlowPathInputEvent(CompositeType):
|
|||||||
for c in [PointerEvent, ScancodeKeyEvent, UnicodeKeyEvent]:
|
for c in [PointerEvent, ScancodeKeyEvent, UnicodeKeyEvent]:
|
||||||
if self.messageType.value == c._INPUT_MESSAGE_TYPE_:
|
if self.messageType.value == c._INPUT_MESSAGE_TYPE_:
|
||||||
return c()
|
return c()
|
||||||
print "WARNING : unknown slow path input : %s"%hex(self.messageType.value)
|
log.debug("unknown slow path input : %s"%hex(self.messageType.value))
|
||||||
return String()
|
return String()
|
||||||
|
|
||||||
if messageData is None:
|
if messageData is None:
|
||||||
@@ -1219,7 +1219,7 @@ class PDULayer(LayerAutomata, tpkt.FastPathListener):
|
|||||||
if ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo):
|
if ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo):
|
||||||
message = ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo]
|
message = ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo]
|
||||||
|
|
||||||
print "Error INFO PDU : %s"%message
|
log.error("INFO PDU : %s"%message)
|
||||||
elif dataPDU.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_SHUTDOWN_DENIED:
|
elif dataPDU.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_SHUTDOWN_DENIED:
|
||||||
#may be an event to ask to user
|
#may be an event to ask to user
|
||||||
self._transport.close()
|
self._transport.close()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
from rdpy.network.type import UInt8, UInt16Be, UInt32Be, String
|
from rdpy.network.type import UInt8, UInt16Be, UInt32Be, String
|
||||||
from rdpy.network.error import InvalidValue, InvalidExpectedDataException
|
from rdpy.base.error import InvalidValue, InvalidExpectedDataException
|
||||||
|
|
||||||
def readLength(s):
|
def readLength(s):
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ Use to manage RDP stack in twisted
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from twisted.internet import protocol
|
from twisted.internet import protocol
|
||||||
from rdpy.network.error import CallPureVirtualFuntion, InvalidValue
|
from rdpy.base.error import CallPureVirtualFuntion, InvalidValue
|
||||||
from rdpy.network.layer import LayerMode
|
from rdpy.network.layer import LayerMode
|
||||||
|
import rdpy.base.log as log
|
||||||
import tpkt, tpdu, mcs, pdu, gcc
|
import tpkt, tpdu, mcs, pdu, gcc
|
||||||
|
|
||||||
class RDPClientController(pdu.PDUClientListener):
|
class RDPClientController(pdu.PDUClientListener):
|
||||||
@@ -153,7 +154,7 @@ class RDPClientController(pdu.PDUClientListener):
|
|||||||
self._pduLayer.sendInputEvents([event])
|
self._pduLayer.sendInputEvents([event])
|
||||||
|
|
||||||
except InvalidValue:
|
except InvalidValue:
|
||||||
print "try send pointer event with incorrect position"
|
log.info("try send pointer event with incorrect position")
|
||||||
|
|
||||||
def sendKeyEventScancode(self, code, isPressed):
|
def sendKeyEventScancode(self, code, isPressed):
|
||||||
"""
|
"""
|
||||||
@@ -176,7 +177,7 @@ class RDPClientController(pdu.PDUClientListener):
|
|||||||
self._pduLayer.sendInputEvents([event])
|
self._pduLayer.sendInputEvents([event])
|
||||||
|
|
||||||
except InvalidValue:
|
except InvalidValue:
|
||||||
print "try send bad key event"
|
log.info("try send bad key event")
|
||||||
|
|
||||||
def sendKeyEventUnicode(self, code, isPressed):
|
def sendKeyEventUnicode(self, code, isPressed):
|
||||||
"""
|
"""
|
||||||
@@ -197,7 +198,7 @@ class RDPClientController(pdu.PDUClientListener):
|
|||||||
self._pduLayer.sendInputEvents([event])
|
self._pduLayer.sendInputEvents([event])
|
||||||
|
|
||||||
except InvalidValue:
|
except InvalidValue:
|
||||||
print "try send bad key event"
|
log.info("try send bad key event")
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ RDP basic security is not supported by RDPY (because is not a true security laye
|
|||||||
|
|
||||||
from rdpy.network.layer import LayerAutomata, LayerMode, StreamSender
|
from rdpy.network.layer import LayerAutomata, LayerMode, StreamSender
|
||||||
from rdpy.network.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof
|
from rdpy.network.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof
|
||||||
from rdpy.network.error import InvalidExpectedDataException
|
from rdpy.base.error import InvalidExpectedDataException
|
||||||
|
|
||||||
class MessageType(object):
|
class MessageType(object):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Use to build correct size packet and handle slow path and fast path mode
|
|||||||
"""
|
"""
|
||||||
from rdpy.network.layer import RawLayer, LayerMode
|
from rdpy.network.layer import RawLayer, LayerMode
|
||||||
from rdpy.network.type import UInt8, UInt16Be, sizeof
|
from rdpy.network.type import UInt8, UInt16Be, sizeof
|
||||||
from rdpy.network.error import CallPureVirtualFuntion
|
from rdpy.base.error import CallPureVirtualFuntion
|
||||||
|
|
||||||
class FastPathListener(object):
|
class FastPathListener(object):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Implement Remote FrameBuffer protocol use in VNC client and server
|
|||||||
from twisted.internet import protocol
|
from twisted.internet import protocol
|
||||||
from rdpy.network.layer import RawLayer, LayerMode
|
from rdpy.network.layer import RawLayer, LayerMode
|
||||||
from rdpy.network.type import UInt8, UInt16Be, UInt32Be, SInt32Be, String, CompositeType
|
from rdpy.network.type import UInt8, UInt16Be, UInt32Be, SInt32Be, String, CompositeType
|
||||||
from rdpy.network.error import InvalidValue, CallPureVirtualFuntion, InvalidType
|
from rdpy.base.error import InvalidValue, CallPureVirtualFuntion, InvalidType
|
||||||
|
|
||||||
class ProtocolVersion(object):
|
class ProtocolVersion(object):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -26,8 +26,14 @@ QRemoteDesktop is a widget use for render in rdpy
|
|||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
from rdpy.protocol.rfb.rfb import RFBClientObserver
|
from rdpy.protocol.rfb.rfb import RFBClientObserver
|
||||||
from rdpy.protocol.rdp.rdp import RDPClientObserver
|
from rdpy.protocol.rdp.rdp import RDPClientObserver
|
||||||
from rdpy.network.error import CallPureVirtualFuntion
|
from rdpy.base.error import CallPureVirtualFuntion
|
||||||
import rle
|
|
||||||
|
import rdpy.base.log as log
|
||||||
|
|
||||||
|
try:
|
||||||
|
import rdpy.core.rle as rle
|
||||||
|
except:
|
||||||
|
log.error("Please build core package before using RLE algorithm : scons -C rdpy/core install")
|
||||||
|
|
||||||
|
|
||||||
class QAdaptor(object):
|
class QAdaptor(object):
|
||||||
@@ -97,7 +103,7 @@ class RFBClientQt(RFBClientObserver, QAdaptor):
|
|||||||
if pixelFormat.BitsPerPixel.value == 32 and pixelFormat.RedShift.value == 16:
|
if pixelFormat.BitsPerPixel.value == 32 and pixelFormat.RedShift.value == 16:
|
||||||
imageFormat = QtGui.QImage.Format_RGB32
|
imageFormat = QtGui.QImage.Format_RGB32
|
||||||
else:
|
else:
|
||||||
print "Receive image in bad format"
|
log.error("Receive image in bad format")
|
||||||
return
|
return
|
||||||
|
|
||||||
image = QtGui.QImage(data, width, height, imageFormat)
|
image = QtGui.QImage(data, width, height, imageFormat)
|
||||||
@@ -218,7 +224,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
|
|||||||
else:
|
else:
|
||||||
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB32)
|
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB32)
|
||||||
else:
|
else:
|
||||||
print "Receive image in bad format"
|
log.error("Receive image in bad format")
|
||||||
return
|
return
|
||||||
|
|
||||||
#if image need to be cut
|
#if image need to be cut
|
||||||
@@ -290,8 +296,6 @@ class QRemoteDesktop(QtGui.QWidget):
|
|||||||
Call when mouse move
|
Call when mouse move
|
||||||
@param event: QMouseEvent
|
@param event: QMouseEvent
|
||||||
"""
|
"""
|
||||||
if self._adaptor is None:
|
|
||||||
print "No adaptor to send mouse move event"
|
|
||||||
self._adaptor.sendMouseEvent(event, False)
|
self._adaptor.sendMouseEvent(event, False)
|
||||||
|
|
||||||
def mousePressEvent(self, event):
|
def mousePressEvent(self, event):
|
||||||
|
|||||||
@@ -2,19 +2,19 @@
|
|||||||
@author: sylvain
|
@author: sylvain
|
||||||
'''
|
'''
|
||||||
import unittest
|
import unittest
|
||||||
import rdpy.network.const
|
import rdpy.base.const
|
||||||
import rdpy.network.type
|
import rdpy.network.type
|
||||||
|
|
||||||
class ConstCase(unittest.TestCase):
|
class ConstCase(unittest.TestCase):
|
||||||
'''
|
'''
|
||||||
represent test case for all classes and function
|
represent test case for all classes and function
|
||||||
present in rdpy.network.const
|
present in rdpy.base.const
|
||||||
'''
|
'''
|
||||||
def test_type_attributes(self):
|
def test_type_attributes(self):
|
||||||
'''
|
'''
|
||||||
test if type attributes decorator works
|
test if type attributes decorator works
|
||||||
'''
|
'''
|
||||||
@rdpy.network.const.TypeAttributes(rdpy.network.type.UInt16Le)
|
@rdpy.base.const.TypeAttributes(rdpy.network.type.UInt16Le)
|
||||||
class Test:
|
class Test:
|
||||||
MEMBER_1 = 1
|
MEMBER_1 = 1
|
||||||
MEMBER_2 = 2
|
MEMBER_2 = 2
|
||||||
@@ -26,7 +26,7 @@ class ConstCase(unittest.TestCase):
|
|||||||
'''
|
'''
|
||||||
test if get on const class member generate new object each
|
test if get on const class member generate new object each
|
||||||
'''
|
'''
|
||||||
@rdpy.network.const.ConstAttributes
|
@rdpy.base.const.ConstAttributes
|
||||||
class Test:
|
class Test:
|
||||||
MEMBER_1 = 1
|
MEMBER_1 = 1
|
||||||
MEMBER_2 = 2
|
MEMBER_2 = 2
|
||||||
@@ -26,17 +26,6 @@ class LayerCase(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(LayerCase.LayerCaseException, rdpy.network.layer.Layer(presentation = TestConnect()).connect)
|
self.assertRaises(LayerCase.LayerCaseException, rdpy.network.layer.Layer(presentation = TestConnect()).connect)
|
||||||
|
|
||||||
def test_layer_receive_event(self):
|
|
||||||
'''
|
|
||||||
test if recv event is send from transport to presentation
|
|
||||||
'''
|
|
||||||
class TestConnect(rdpy.network.layer.Layer):
|
|
||||||
def recv(self, s):
|
|
||||||
if s == "message":
|
|
||||||
raise LayerCase.LayerCaseException()
|
|
||||||
|
|
||||||
self.assertRaises(LayerCase.LayerCaseException, rdpy.network.layer.Layer(presentation = TestConnect()).recv, "message")
|
|
||||||
|
|
||||||
def test_layer_automata_more_than_expected(self):
|
def test_layer_automata_more_than_expected(self):
|
||||||
'''
|
'''
|
||||||
test layer automata mechanism if data received is more than expected
|
test layer automata mechanism if data received is more than expected
|
||||||
@@ -331,20 +331,4 @@ class TypeCase(unittest.TestCase):
|
|||||||
except Exception:
|
except Exception:
|
||||||
self.assertEqual(s.readLen(), 0, "invalid stream roll back operation")
|
self.assertEqual(s.readLen(), 0, "invalid stream roll back operation")
|
||||||
return
|
return
|
||||||
self.assertTrue(False, "Constant constraint fail")
|
self.assertTrue(False, "Constant constraint fail")
|
||||||
|
|
||||||
def test_stream_composite_type_force_read_length_optional(self):
|
|
||||||
'''
|
|
||||||
test where type have readLen forced and have optional subtype which have
|
|
||||||
length greater than last subtype of composite type
|
|
||||||
'''
|
|
||||||
class TestType(rdpy.network.type.CompositeType):
|
|
||||||
def __init__(self, readLen = None):
|
|
||||||
rdpy.network.type.CompositeType.__init__(self, readLen = readLen)
|
|
||||||
self.t1 = rdpy.network.type.UInt32Le(0, optional = True)
|
|
||||||
self.t2 = rdpy.network.type.UInt16Le(0, optional = True)
|
|
||||||
|
|
||||||
s = rdpy.network.type.Stream("\x00\x00\x00\x00\x00\x00\x00")
|
|
||||||
t = TestType(readLen = rdpy.network.type.UInt8(2))
|
|
||||||
s.readType(t)
|
|
||||||
self.assertTrue(not t.t1._is_readed and t.t2._is_readed, "Invalid optional reading when length is forced")
|
|
||||||
Reference in New Issue
Block a user