bug fix on server side, add log engine, change lib to core

This commit is contained in:
citronneur
2014-07-20 14:59:53 +02:00
parent f51ef15865
commit 67845e50ad
31 changed files with 187 additions and 171 deletions

2
.gitignore vendored
View File

@@ -2,7 +2,7 @@
.project
.pydevproject
README.md~
lib/build/*
rdpy/core/tmp/*
*.so
*.os
.sconsign.dblite

View File

@@ -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
View 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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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)
return cls

View File

@@ -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

View File

@@ -16,7 +16,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from rdpy.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)

View File

@@ -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))

View File

@@ -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:

View File

@@ -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):
"""

View File

@@ -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()

View File

@@ -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):
'''

View File

@@ -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):
"""

View File

@@ -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):
"""

View File

@@ -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):
"""

View File

@@ -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):
"""

View File

@@ -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):

View File

@@ -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

View File

@@ -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

View File

@@ -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")
self.assertTrue(False, "Constant constraint fail")