diff --git a/.gitignore b/.gitignore
index 0964ec0..b8f27d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@
.project
.pydevproject
README.md~
-lib/build/*
+rdpy/core/tmp/*
*.so
*.os
.sconsign.dblite
diff --git a/bin/rdpy-test b/bin/rdpy-test
deleted file mode 100755
index bd3e233..0000000
--- a/bin/rdpy-test
+++ /dev/null
@@ -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 .
-#
-
-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)
-
diff --git a/rdpy/tests/__init__.py b/rdpy/base/__init__.py
similarity index 100%
rename from rdpy/tests/__init__.py
rename to rdpy/base/__init__.py
diff --git a/rdpy/network/const.py b/rdpy/base/const.py
similarity index 100%
rename from rdpy/network/const.py
rename to rdpy/base/const.py
diff --git a/rdpy/network/error.py b/rdpy/base/error.py
similarity index 100%
rename from rdpy/network/error.py
rename to rdpy/base/error.py
diff --git a/rdpy/base/log.py b/rdpy/base/log.py
new file mode 100644
index 0000000..a6433e3
--- /dev/null
+++ b/rdpy/base/log.py
@@ -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 .
+#
+
+"""
+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)
\ No newline at end of file
diff --git a/rdpy/tests/network/__init__.py b/rdpy/core/__init__.py
similarity index 100%
rename from rdpy/tests/network/__init__.py
rename to rdpy/core/__init__.py
diff --git a/lib/sconstruct b/rdpy/core/sconstruct
similarity index 70%
rename from lib/sconstruct
rename to rdpy/core/sconstruct
index c76e8de..f541ac5 100644
--- a/lib/sconstruct
+++ b/rdpy/core/sconstruct
@@ -2,7 +2,7 @@ import os
import sipconfig
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")
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])]))
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)
lib = env.SharedLibrary(target = targetName, source = sources, SHLIBPREFIX='')
@@ -31,6 +31,6 @@ def build_module(name, install_dir, env):
env = Environment()
env.Append(BUILDERS = {'Sip' : Builder(action = build_sip)})
env.Append(CPPPATH = ["/usr/include/python2.7"]);
-env.VariantDir('build', 'src', duplicate=0)
-build_module("rle", os.path.join(script_dir, "..", "rdpy", "ui"), env)
+env.VariantDir('tmp', 'src', duplicate=0)
+build_module("rle", script_dir, env)
diff --git a/lib/sip/rle.sip b/rdpy/core/sip/rle.sip
similarity index 100%
rename from lib/sip/rle.sip
rename to rdpy/core/sip/rle.sip
diff --git a/lib/src/rle/rle.c b/rdpy/core/src/rle/rle.c
similarity index 100%
rename from lib/src/rle/rle.c
rename to rdpy/core/src/rle/rle.c
diff --git a/lib/src/rle/rle.h b/rdpy/core/src/rle/rle.h
similarity index 100%
rename from lib/src/rle/rle.h
rename to rdpy/core/src/rle/rle.h
diff --git a/rdpy/network/layer.py b/rdpy/network/layer.py
index bd9f5a7..396743c 100644
--- a/rdpy/network/layer.py
+++ b/rdpy/network/layer.py
@@ -23,7 +23,7 @@ Join RDPY design with twisted design
RDPY use Layer Protocol design (like twisted)
"""
-from rdpy.network.error import CallPureVirtualFuntion
+from rdpy.base.error import CallPureVirtualFuntion
class LayerMode(object):
NONE = 0
diff --git a/rdpy/network/type.py b/rdpy/network/type.py
index fd76c7b..40d91cd 100644
--- a/rdpy/network/type.py
+++ b/rdpy/network/type.py
@@ -27,8 +27,8 @@ We are in python we can use that!
import struct
from copy import deepcopy
from StringIO import StringIO
-from error import InvalidValue
-from rdpy.network.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion
+from rdpy.base.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion, InvalidValue
+import rdpy.base.log as log
def sizeof(element):
"""
@@ -432,7 +432,7 @@ class CompositeType(Type):
raise InvalidSize("Impossible to read type %s : read length is too small"%(self.__class__))
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
for tmpName in self._typeName:
if tmpName == name:
@@ -440,7 +440,7 @@ class CompositeType(Type):
s.pos -= sizeof(self.__dict__[tmpName])
raise e
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)
def __write__(self, s):
@@ -452,7 +452,7 @@ class CompositeType(Type):
try:
s.writeType(self.__dict__[name])
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
def __sizeof__(self):
@@ -949,16 +949,4 @@ def CheckValueOnRead(cls):
if self != old:
raise InvalidValue("CheckValueOnRead %s != %s"%(self, old))
cls.read = read
- 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)
\ No newline at end of file
+ return cls
\ No newline at end of file
diff --git a/rdpy/protocol/rdp/ber.py b/rdpy/protocol/rdp/ber.py
index 32af834..7c9eea5 100644
--- a/rdpy/protocol/rdp/ber.py
+++ b/rdpy/protocol/rdp/ber.py
@@ -23,7 +23,7 @@ ASN.1 standard
"""
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):
BER_PC_MASK = 0x20
diff --git a/rdpy/protocol/rdp/caps.py b/rdpy/protocol/rdp/caps.py
index c51f8a9..6189082 100644
--- a/rdpy/protocol/rdp/caps.py
+++ b/rdpy/protocol/rdp/caps.py
@@ -16,7 +16,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
-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
@@ -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]:
if self.capabilitySetType.value == c._TYPE_:
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
return String(readLen = self.lengthCapability - 4)
diff --git a/rdpy/protocol/rdp/gcc.py b/rdpy/protocol/rdp/gcc.py
index 735da1f..c782959 100644
--- a/rdpy/protocol/rdp/gcc.py
+++ b/rdpy/protocol/rdp/gcc.py
@@ -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
-import per
-from rdpy.network.error import InvalidExpectedDataException
+import per, mcs
+from rdpy.base.error import InvalidExpectedDataException
+import rdpy.base.log as log
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]:
if self.type.value == c._TYPE_:
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
return String(readLen = self.length - 4)
@@ -285,8 +286,7 @@ class ServerSecurityData(CompositeType):
def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen)
self.encryptionMethod = UInt32Le()
- self.encryptionLevel = UInt32Le()
-
+ self.encryptionLevel = UInt32Le()
class ChannelDef(CompositeType):
"""
@@ -310,7 +310,7 @@ class ClientNetworkData(CompositeType):
def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen)
- self.channelCount = UInt32Le()
+ self.channelCount = UInt32Le(lambda:len(self.channelDefArray._array))
self.channelDefArray = ArrayType(ChannelDef, readLen = self.channelCount)
class ServerNetworkData(CompositeType):
@@ -323,7 +323,7 @@ class ServerNetworkData(CompositeType):
def __init__(self, readLen = None):
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.channelIdArray = ArrayType(UInt16Le, readLen = self.channelCount)
self.pad = UInt16Le(conditional = lambda:((self.channelCount.value % 2) == 1))
diff --git a/rdpy/protocol/rdp/lic.py b/rdpy/protocol/rdp/lic.py
index ae91144..c882437 100644
--- a/rdpy/protocol/rdp/lic.py
+++ b/rdpy/protocol/rdp/lic.py
@@ -23,7 +23,8 @@ RDP extended license
"""
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):
"""
@@ -193,7 +194,7 @@ class LicPacket(CompositeType):
for c in [LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest]:
if self.bMsgtype.value == c._MESSAGE_TYPE_:
return c()
- print "WARNING : unknown license message : %s"%self.bMsgtype.value
+ log.debug("unknown license message : %s"%self.bMsgtype.value)
return String()
if message is None:
diff --git a/rdpy/protocol/rdp/mcs.py b/rdpy/protocol/rdp/mcs.py
index fa103ac..b84f9ee 100644
--- a/rdpy/protocol/rdp/mcs.py
+++ b/rdpy/protocol/rdp/mcs.py
@@ -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.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
+import rdpy.base.log as log
import ber, gcc, per
@@ -115,10 +116,11 @@ class MCS(LayerAutomata):
return self._mcs._serverSettings
- def __init__(self, mode, presentation):
+ def __init__(self, mode, presentation, virtualChannels = []):
"""
@param mode: mode of MCS layer
@param presentation: presentation layer
+ @param virtualChannels: list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
"""
LayerAutomata.__init__(self, mode, presentation)
self._clientSettings = gcc.clientSettings()
@@ -126,7 +128,13 @@ class MCS(LayerAutomata):
#default user Id
self._userId = 1 + Channel.MCS_USERCHANNEL_BASE
#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
self._channelIdsRequested = {}
@@ -137,7 +145,12 @@ class MCS(LayerAutomata):
"""
if self._mode == LayerMode.CLIENT:
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()
+ #next wait response
+ self.setNextState(self.recvConnectResponse)
else:
self._serverSettings.getBlock(gcc.MessageType.SC_CORE).clientRequestedProtocol.value = self._transport._requestedProtocol
self.setNextState(self.recvConnectInitial)
@@ -147,21 +160,41 @@ class MCS(LayerAutomata):
Send sendChannelJoinRequest message on next disconnect channel
client automata function
"""
- for (channelId, layer) in self._channelIds.iteritems():
- #for each disconnect channel send a request
- if not self._channelIdsRequested.has_key(channelId):
- self.sendChannelJoinRequest(channelId)
- self.setNextState(self.recvChannelJoinConfirm)
- return
-
+ self.setNextState(self.recvChannelJoinConfirm)
+ #global channel
+ if not self._isGlobalChannelRequested:
+ self.sendChannelJoinRequest(Channel.MCS_GLOBAL_CHANNEL)
+ self._isGlobalChannelRequested = True
+ 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
self.setNextState(self.recvData)
#try connection on all requested channel
- for (channelId, layer) in self._channelIds.iteritems():
- if self._channelIdsRequested[channelId] and not layer is None:
- #use proxy for each channel
- layer._transport = MCS.MCSProxySender(self, channelId)
- layer.connect()
+ for (channelId, layer) in self._channels.iteritems():
+ #use proxy for each channel
+ layer._transport = MCS.MCSProxySender(self, channelId)
+ layer.connect()
def sendConnectInitial(self):
"""
@@ -178,8 +211,6 @@ class MCS(LayerAutomata):
self.writeDomainParams(0xffff, 0xfc17, 0xffff, 0xffff),
ber.writeOctetstring(ccReqStream.getvalue()))
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):
"""
@@ -194,8 +225,6 @@ class MCS(LayerAutomata):
ber.writeOctetstring(ccReqStream.getvalue()))
self._transport.send((ber.writeApplicationTag(Message.MCS_TYPE_CONNECT_RESPONSE, sizeof(tmp)), tmp))
- self.setNextState(self.recvErectDomainRequest)
-
def sendErectDomainRequest(self):
"""
Send a formated erect domain request for RDP connection
@@ -217,7 +246,7 @@ class MCS(LayerAutomata):
Send attach user confirm
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.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE)))
@@ -237,7 +266,7 @@ class MCS(LayerAutomata):
@param channelId: id of channel
@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.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
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.sendConnectResponse()
+ self.setNextState(self.recvErectDomainRequest)
def recvConnectResponse(self, data):
"""
@@ -350,10 +380,6 @@ class MCS(LayerAutomata):
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()
def recvChannelJoinRequest(self, data):
@@ -374,7 +400,12 @@ class MCS(LayerAutomata):
raise InvalidExpectedDataException("Invalid MCS User Id")
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):
"""
@@ -395,8 +426,16 @@ class MCS(LayerAutomata):
raise InvalidExpectedDataException("Invalid MCS User Id")
channelId = per.readInteger16(data)
- #save state of channel
- self._channelIdsRequested[channelId] = (confirm == 0)
+ #must confirm global channel and user channel
+ 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()
def recvData(self, data):
@@ -408,7 +447,7 @@ class MCS(LayerAutomata):
data.readType(opcode)
if self.readMCSPDUHeader(opcode.value, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
- print "INFO : MCS DISCONNECT_PROVIDER_ULTIMATUM"
+ log.info("MCS DISCONNECT_PROVIDER_ULTIMATUM")
self._transport.close()
return
@@ -424,16 +463,11 @@ class MCS(LayerAutomata):
per.readLength(data)
#channel id doesn't match a requested layer
- if not self._channelIdsRequested.has_key(channelId):
- print "ERROR : receive data for an unrequested layer"
+ if not self._channels.has_key(channelId):
+ log.error("receive data for an unconnected layer")
return
-
- #channel id math an unconnected layer
- if not self._channelIdsRequested[channelId]:
- print "ERROR : receive data for an unconnected layer"
- return
-
- self._channelIds[channelId].recv(data)
+
+ self._channels[channelId].recv(data)
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
"""
diff --git a/rdpy/protocol/rdp/pdu.py b/rdpy/protocol/rdp/pdu.py
index 141d937..b2257a6 100644
--- a/rdpy/protocol/rdp/pdu.py
+++ b/rdpy/protocol/rdp/pdu.py
@@ -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.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
class SecurityFlag(object):
@@ -562,7 +562,7 @@ class PDU(CompositeType):
for c in [DemandActivePDU, ConfirmActivePDU, DataPDU, DeactiveAllPDU]:
if self.shareControlHeader.pduType.value == c._PDUTYPE_:
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
return String()
@@ -643,7 +643,7 @@ class DataPDU(CompositeType):
for c in [UpdateDataPDU, SynchronizeDataPDU, ControlDataPDU, ErrorInfoDataPDU, FontListDataPDU, FontMapDataPDU, PersistentListPDU, ClientInputEventPDU, ShutdownDeniedPDU, ShutdownRequestPDU]:
if self.shareDataHeader.pduType2.value == c._PDUTYPE2_:
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()
if pduData is None:
@@ -936,7 +936,7 @@ class SlowPathInputEvent(CompositeType):
for c in [PointerEvent, ScancodeKeyEvent, UnicodeKeyEvent]:
if self.messageType.value == c._INPUT_MESSAGE_TYPE_:
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()
if messageData is None:
@@ -1219,7 +1219,7 @@ class PDULayer(LayerAutomata, tpkt.FastPathListener):
if ErrorInfo._MESSAGES_.has_key(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:
#may be an event to ask to user
self._transport.close()
diff --git a/rdpy/protocol/rdp/per.py b/rdpy/protocol/rdp/per.py
index f74a5dd..e9f843d 100644
--- a/rdpy/protocol/rdp/per.py
+++ b/rdpy/protocol/rdp/per.py
@@ -3,7 +3,7 @@
'''
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):
'''
diff --git a/rdpy/protocol/rdp/rdp.py b/rdpy/protocol/rdp/rdp.py
index 3f7b390..7f3057b 100644
--- a/rdpy/protocol/rdp/rdp.py
+++ b/rdpy/protocol/rdp/rdp.py
@@ -22,8 +22,9 @@ Use to manage RDP stack in twisted
"""
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
+import rdpy.base.log as log
import tpkt, tpdu, mcs, pdu, gcc
class RDPClientController(pdu.PDUClientListener):
@@ -153,7 +154,7 @@ class RDPClientController(pdu.PDUClientListener):
self._pduLayer.sendInputEvents([event])
except InvalidValue:
- print "try send pointer event with incorrect position"
+ log.info("try send pointer event with incorrect position")
def sendKeyEventScancode(self, code, isPressed):
"""
@@ -176,7 +177,7 @@ class RDPClientController(pdu.PDUClientListener):
self._pduLayer.sendInputEvents([event])
except InvalidValue:
- print "try send bad key event"
+ log.info("try send bad key event")
def sendKeyEventUnicode(self, code, isPressed):
"""
@@ -197,7 +198,7 @@ class RDPClientController(pdu.PDUClientListener):
self._pduLayer.sendInputEvents([event])
except InvalidValue:
- print "try send bad key event"
+ log.info("try send bad key event")
def close(self):
"""
diff --git a/rdpy/protocol/rdp/tpdu.py b/rdpy/protocol/rdp/tpdu.py
index 1673e80..7ffd9eb 100644
--- a/rdpy/protocol/rdp/tpdu.py
+++ b/rdpy/protocol/rdp/tpdu.py
@@ -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.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof
-from rdpy.network.error import InvalidExpectedDataException
+from rdpy.base.error import InvalidExpectedDataException
class MessageType(object):
"""
diff --git a/rdpy/protocol/rdp/tpkt.py b/rdpy/protocol/rdp/tpkt.py
index 0cb0648..12ca336 100644
--- a/rdpy/protocol/rdp/tpkt.py
+++ b/rdpy/protocol/rdp/tpkt.py
@@ -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.type import UInt8, UInt16Be, sizeof
-from rdpy.network.error import CallPureVirtualFuntion
+from rdpy.base.error import CallPureVirtualFuntion
class FastPathListener(object):
"""
diff --git a/rdpy/protocol/rfb/rfb.py b/rdpy/protocol/rfb/rfb.py
index 14097c1..faddffc 100644
--- a/rdpy/protocol/rfb/rfb.py
+++ b/rdpy/protocol/rfb/rfb.py
@@ -29,7 +29,7 @@ Implement Remote FrameBuffer protocol use in VNC client and server
from twisted.internet import protocol
from rdpy.network.layer import RawLayer, LayerMode
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):
"""
diff --git a/rdpy/tests/protocol/__init__.py b/rdpy/tests/protocol/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/rdpy/tests/protocol/rfb/__init__.py b/rdpy/tests/protocol/rfb/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/rdpy/ui/qt4.py b/rdpy/ui/qt4.py
index 5207eb6..908e518 100644
--- a/rdpy/ui/qt4.py
+++ b/rdpy/ui/qt4.py
@@ -26,8 +26,14 @@ QRemoteDesktop is a widget use for render in rdpy
from PyQt4 import QtGui, QtCore
from rdpy.protocol.rfb.rfb import RFBClientObserver
from rdpy.protocol.rdp.rdp import RDPClientObserver
-from rdpy.network.error import CallPureVirtualFuntion
-import rle
+from rdpy.base.error import CallPureVirtualFuntion
+
+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):
@@ -97,7 +103,7 @@ class RFBClientQt(RFBClientObserver, QAdaptor):
if pixelFormat.BitsPerPixel.value == 32 and pixelFormat.RedShift.value == 16:
imageFormat = QtGui.QImage.Format_RGB32
else:
- print "Receive image in bad format"
+ log.error("Receive image in bad format")
return
image = QtGui.QImage(data, width, height, imageFormat)
@@ -218,7 +224,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
else:
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB32)
else:
- print "Receive image in bad format"
+ log.error("Receive image in bad format")
return
#if image need to be cut
@@ -290,8 +296,6 @@ class QRemoteDesktop(QtGui.QWidget):
Call when mouse move
@param event: QMouseEvent
"""
- if self._adaptor is None:
- print "No adaptor to send mouse move event"
self._adaptor.sendMouseEvent(event, False)
def mousePressEvent(self, event):
diff --git a/rdpy/tests/network/const.py b/tests/const.py
similarity index 83%
rename from rdpy/tests/network/const.py
rename to tests/const.py
index e5d99ae..46c2339 100644
--- a/rdpy/tests/network/const.py
+++ b/tests/const.py
@@ -2,19 +2,19 @@
@author: sylvain
'''
import unittest
-import rdpy.network.const
+import rdpy.base.const
import rdpy.network.type
class ConstCase(unittest.TestCase):
'''
represent test case for all classes and function
- present in rdpy.network.const
+ present in rdpy.base.const
'''
def test_type_attributes(self):
'''
test if type attributes decorator works
'''
- @rdpy.network.const.TypeAttributes(rdpy.network.type.UInt16Le)
+ @rdpy.base.const.TypeAttributes(rdpy.network.type.UInt16Le)
class Test:
MEMBER_1 = 1
MEMBER_2 = 2
@@ -26,7 +26,7 @@ class ConstCase(unittest.TestCase):
'''
test if get on const class member generate new object each
'''
- @rdpy.network.const.ConstAttributes
+ @rdpy.base.const.ConstAttributes
class Test:
MEMBER_1 = 1
MEMBER_2 = 2
diff --git a/rdpy/tests/network/layer.py b/tests/layer.py
similarity index 80%
rename from rdpy/tests/network/layer.py
rename to tests/layer.py
index bfa35da..0f67cf2 100644
--- a/rdpy/tests/network/layer.py
+++ b/tests/layer.py
@@ -26,17 +26,6 @@ class LayerCase(unittest.TestCase):
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):
'''
test layer automata mechanism if data received is more than expected
diff --git a/rdpy/tests/protocol/rfb/rfb.py b/tests/rfb.py
similarity index 100%
rename from rdpy/tests/protocol/rfb/rfb.py
rename to tests/rfb.py
diff --git a/rdpy/tests/network/type.py b/tests/type.py
similarity index 93%
rename from rdpy/tests/network/type.py
rename to tests/type.py
index 6fecfcb..083eab5 100644
--- a/rdpy/tests/network/type.py
+++ b/tests/type.py
@@ -331,20 +331,4 @@ class TypeCase(unittest.TestCase):
except Exception:
self.assertEqual(s.readLen(), 0, "invalid stream roll back operation")
return
- 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")
\ No newline at end of file
+ self.assertTrue(False, "Constant constraint fail")
\ No newline at end of file