From 4fa22177b443dcfc235b6eadc97566e15cc2b0e5 Mon Sep 17 00:00:00 2001 From: speyrefitte Date: Tue, 1 Jul 2014 17:52:20 +0200 Subject: [PATCH] bug fix and code refactoring --- rdpy/network/type.py | 4 +- rdpy/protocol/rdp/ber.py | 39 +++--- rdpy/protocol/rdp/caps.py | 279 ++++++++++++++++++-------------------- rdpy/protocol/rdp/gcc.py | 277 ++++++++++++++++++------------------- rdpy/protocol/rdp/mcs.py | 2 +- rdpy/protocol/rdp/pdu.py | 157 ++++++++++----------- rdpy/protocol/rdp/rdp.py | 4 +- rdpy/protocol/rfb/rfb.py | 89 +++++++----- 8 files changed, 415 insertions(+), 436 deletions(-) diff --git a/rdpy/network/type.py b/rdpy/network/type.py index eb69eda..4949d5b 100644 --- a/rdpy/network/type.py +++ b/rdpy/network/type.py @@ -261,7 +261,7 @@ class SimpleType(Type, CallableValue): """ if not self.__dict__.has_key("_mask"): mask = 0xff - for i in range(1, self._typeSize): + for _ in range(1, self._typeSize): mask = mask << 8 | 0xff self._mask = mask return self._mask @@ -844,7 +844,7 @@ class ArrayType(Type): @param s: Stream ''' self._array = [] - for i in range(0, self._readLen.value): + for _ in range(0, self._readLen.value): element = self._typeFactory() s.readType(element) self._array.append(element) diff --git a/rdpy/protocol/rdp/ber.py b/rdpy/protocol/rdp/ber.py index 5e6eabc..9a91928 100644 --- a/rdpy/protocol/rdp/ber.py +++ b/rdpy/protocol/rdp/ber.py @@ -23,27 +23,20 @@ ASN.1 standard """ from rdpy.network.type import UInt8, UInt16Be, UInt32Be, String -from rdpy.network.const import ConstAttributes, TypeAttributes from rdpy.network.error import InvalidExpectedDataException, InvalidSize -@ConstAttributes -@TypeAttributes(UInt8) class BerPc(object): BER_PC_MASK = 0x20 BER_PRIMITIVE = 0x00 BER_CONSTRUCT = 0x20 -@ConstAttributes -@TypeAttributes(UInt8) class Class(object): BER_CLASS_MASK = 0xC0 BER_CLASS_UNIV = 0x00 BER_CLASS_APPL = 0x40 BER_CLASS_CTXT = 0x80 BER_CLASS_PRIV = 0xC0 - -@ConstAttributes -@TypeAttributes(UInt8) + class Tag(object): BER_TAG_MASK = 0x1F BER_TAG_BOOLEAN = 0x01 @@ -111,7 +104,7 @@ def readUniversalTag(s, tag, pc): """ byte = UInt8() s.readType(byte) - return byte == ((Class.BER_CLASS_UNIV | berPC(pc)) | (Tag.BER_TAG_MASK & tag)) + return byte.value == ((Class.BER_CLASS_UNIV | berPC(pc)) | (Tag.BER_TAG_MASK & tag)) def writeUniversalTag(tag, pc): """ @@ -120,7 +113,7 @@ def writeUniversalTag(tag, pc): @param pc: boolean @return: UInt8 """ - return ((Class.BER_CLASS_UNIV | berPC(pc)) | (Tag.BER_TAG_MASK & tag)) + return UInt8((Class.BER_CLASS_UNIV | berPC(pc)) | (Tag.BER_TAG_MASK & tag)) def readApplicationTag(s, tag): """ @@ -131,14 +124,14 @@ def readApplicationTag(s, tag): """ byte = UInt8() s.readType(byte) - if tag > UInt8(30): - if byte != ((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | Tag.BER_TAG_MASK): + if tag.value > 30: + if byte.value != ((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | Tag.BER_TAG_MASK): raise InvalidExpectedDataException() s.readType(byte) - if byte != tag: + if byte.value != tag.value: raise InvalidExpectedDataException("bad tag") else: - if byte != ((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | (Tag.BER_TAG_MASK & tag)): + if byte.value != ((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | (Tag.BER_TAG_MASK & tag)): raise InvalidExpectedDataException() return readLength(s) @@ -146,13 +139,13 @@ def readApplicationTag(s, tag): def writeApplicationTag(tag, size): """ Return structure that represent BER application tag - @param tag: UINt8 + @param tag: int python that match an uint8(0xff) @param size: size to rest of packet """ - if tag > UInt8(30): - return (((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | Tag.BER_TAG_MASK), tag, writeLength(size)) + if tag > 30: + return (UInt8((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | Tag.BER_TAG_MASK), UInt8(tag), writeLength(size)) else: - return (((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | (Tag.BER_TAG_MASK & tag)), writeLength(size)) + return (UInt8((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | (Tag.BER_TAG_MASK & tag)), writeLength(size)) def readBoolean(s): """ @@ -215,7 +208,7 @@ def readInteger(s): def writeInteger(value): """ Write integer value - @param param: int or python long + @param param: INT or Python long @return: BER integer structure """ if value <= 0xff: @@ -229,18 +222,18 @@ def readOctetString(s): """ Read BER string structure @param s: stream - @return: String + @return: string python """ if not readUniversalTag(s, Tag.BER_TAG_OCTET_STRING, False): raise InvalidExpectedDataException("Unexpected BER tag") size = readLength(s) - return String(s.read(size.value)) + return s.read(size.value) def writeOctetstring(value): """ - Write string in ber representation + Write string in BER representation @param value: string - @return: string ber structure + @return: string BER structure """ return (writeUniversalTag(Tag.BER_TAG_OCTET_STRING, False), writeLength(len(value)), String(value)) diff --git a/rdpy/protocol/rdp/caps.py b/rdpy/protocol/rdp/caps.py index e12734c..cac40b1 100644 --- a/rdpy/protocol/rdp/caps.py +++ b/rdpy/protocol/rdp/caps.py @@ -1,16 +1,34 @@ -''' -@author: citronneur -''' -from rdpy.network.type import CompositeType, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType -from rdpy.network.const import ConstAttributes, TypeAttributes +# +# 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 . +# -@ConstAttributes -@TypeAttributes(UInt16Le) +""" +Definition of structure use for capabilities nego +Use in PDU layer +""" + +from rdpy.network.type import CompositeType, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType + class CapsType(object): - ''' - different type of capabilities + """ + Different type of capabilities @see: http://msdn.microsoft.com/en-us/library/cc240486.aspx - ''' + """ CAPSTYPE_GENERAL = 0x0001 CAPSTYPE_BITMAP = 0x0002 CAPSTYPE_ORDER = 0x0003 @@ -40,13 +58,11 @@ class CapsType(object): CAPSETTYPE_BITMAP_CODECS = 0x001D CAPSSETTYPE_FRAME_ACKNOWLEDGE = 0x001E -@ConstAttributes -@TypeAttributes(UInt16Le) class MajorType(object): - ''' - use in general capability + """ + Use in general capability @see: http://msdn.microsoft.com/en-us/library/cc240549.aspx - ''' + """ OSMAJORTYPE_UNSPECIFIED = 0x0000 OSMAJORTYPE_WINDOWS = 0x0001 OSMAJORTYPE_OS2 = 0x0002 @@ -55,14 +71,12 @@ class MajorType(object): OSMAJORTYPE_IOS = 0x0005 OSMAJORTYPE_OSX = 0x0006 OSMAJORTYPE_ANDROID = 0x0007 - -@ConstAttributes -@TypeAttributes(UInt16Le) + class MinorType(object): - ''' - use in general capability + """ + Use in general capability @see: http://msdn.microsoft.com/en-us/library/cc240549.aspx - ''' + """ OSMINORTYPE_UNSPECIFIED = 0x0000 OSMINORTYPE_WINDOWS_31X = 0x0001 OSMINORTYPE_WINDOWS_95 = 0x0002 @@ -73,47 +87,39 @@ class MinorType(object): OSMINORTYPE_NATIVE_XSERVER = 0x0007 OSMINORTYPE_PSEUDO_XSERVER = 0x0008 OSMINORTYPE_WINDOWS_RT = 0x0009 - -@ConstAttributes -@TypeAttributes(UInt16Le) + class GeneralExtraFlag(object): - ''' - use in general capability + """ + Use in general capability @see: http://msdn.microsoft.com/en-us/library/cc240549.aspx - ''' + """ FASTPATH_OUTPUT_SUPPORTED = 0x0001 NO_BITMAP_COMPRESSION_HDR = 0x0400 LONG_CREDENTIALS_SUPPORTED = 0x0004 AUTORECONNECT_SUPPORTED = 0x0008 ENC_SALTED_CHECKSUM = 0x0010 - -@ConstAttributes -@TypeAttributes(UInt8) + class Boolean(object): FALSE = 0x00 TRUE = 0x01 - -@ConstAttributes -@TypeAttributes(UInt16Le) + class OrderFlag(object): - ''' - use in order capability + """ + Use in order capability @see: http://msdn.microsoft.com/en-us/library/cc240556.aspx - ''' + """ NEGOTIATEORDERSUPPORT = 0x0002 ZEROBOUNDSDELTASSUPPORT = 0x0008 COLORINDEXSUPPORT = 0x0020 SOLIDPATTERNBRUSHONLY = 0x0040 ORDERFLAGS_EXTRA_FLAGS = 0x0080 - -@ConstAttributes -@TypeAttributes(UInt8) + class Order(object): - ''' - drawing orders supported - use in order capability + """ + Drawing orders supported + Use in order capability @see: http://msdn.microsoft.com/en-us/library/cc240556.aspx - ''' + """ TS_NEG_DSTBLT_INDEX = 0x00 TS_NEG_PATBLT_INDEX = 0x01 TS_NEG_SCRBLT_INDEX = 0x02 @@ -135,25 +141,20 @@ class Order(object): TS_NEG_ELLIPSE_SC_INDEX = 0x19 TS_NEG_ELLIPSE_CB_INDEX = 0x1A TS_NEG_INDEX_INDEX = 0x1B - -@ConstAttributes -@TypeAttributes(UInt16Le) + class OrderEx(object): - ''' - extension orders - use in order capability - ''' + """ + Extension orders + Use in order capability + """ ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT = 0x0002 ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT = 0x0004 - -@ConstAttributes -@TypeAttributes(UInt16Le) class InputFlags(object): - ''' + """ Input flag use in input capability @see: http://msdn.microsoft.com/en-us/library/cc240563.aspx - ''' + """ INPUT_FLAG_SCANCODES = 0x0001 INPUT_FLAG_MOUSEX = 0x0004 INPUT_FLAG_FASTPATH_INPUT = 0x0008 @@ -163,65 +164,55 @@ class InputFlags(object): INPUT_FLAG_UNUSED2 = 0x0080 TS_INPUT_FLAG_MOUSE_HWHEEL = 0x0100 -@ConstAttributes -@TypeAttributes(UInt32Le) class BrushSupport(object): - ''' + """ Brush support of client @see: http://msdn.microsoft.com/en-us/library/cc240564.aspx - ''' + """ BRUSH_DEFAULT = 0x00000000 BRUSH_COLOR_8x8 = 0x00000001 BRUSH_COLOR_FULL = 0x00000002 -@ConstAttributes -@TypeAttributes(UInt16Le) class GlyphSupport(object): - ''' + """ Use by glyph order @see: http://msdn.microsoft.com/en-us/library/cc240565.aspx - ''' + """ GLYPH_SUPPORT_NONE = 0x0000 GLYPH_SUPPORT_PARTIAL = 0x0001 GLYPH_SUPPORT_FULL = 0x0002 GLYPH_SUPPORT_ENCODE = 0x0003 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class OffscreenSupportLevel(object): - ''' + """ Use to determine offscreen cache level supported @see: http://msdn.microsoft.com/en-us/library/cc240550.aspx - ''' + """ FALSE = 0x00000000 TRUE = 0x00000001 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class VirtualChannelCompressionFlag(object): - ''' + """ Use to determine virtual channel compression @see: http://msdn.microsoft.com/en-us/library/cc240551.aspx - ''' + """ VCCAPS_NO_COMPR = 0x00000000 VCCAPS_COMPR_SC = 0x00000001 VCCAPS_COMPR_CS_8K = 0x00000002 - -@ConstAttributes -@TypeAttributes(UInt16Le) + class SoundFlag(object): - ''' + """ Use in sound capability to inform it @see: http://msdn.microsoft.com/en-us/library/cc240552.aspx - ''' + """ NONE = 0x0000 SOUND_BEEPS_FLAG = 0x0001 class CacheEntry(CompositeType): - ''' + """ Use in capability cache exchange @see: http://msdn.microsoft.com/en-us/library/cc240566.aspx - ''' + """ def __init__(self): CompositeType.__init__(self) self.cacheEntries = UInt16Le() @@ -229,50 +220,50 @@ class CacheEntry(CompositeType): class Capability(CompositeType): - ''' + """ A capability @see: http://msdn.microsoft.com/en-us/library/cc240486.aspx - ''' - def __init__(self, capabilitySetType = UInt16Le(), capability = None): + """ + def __init__(self, capabilitySetType = 0, capability = None): CompositeType.__init__(self) - self.capabilitySetType = UInt16Le(capabilitySetType.value, constant = (not capability is None)) + self.capabilitySetType = UInt16Le(capabilitySetType, constant = (not capability is None)) self.lengthCapability = UInt16Le(lambda:sizeof(self)) def CapabilityFactory(): ''' closure for capability factory ''' - if self.capabilitySetType == CapsType.CAPSTYPE_GENERAL: + if self.capabilitySetType.value == CapsType.CAPSTYPE_GENERAL: return GeneralCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_BITMAP: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_BITMAP: return BitmapCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_ORDER: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_ORDER: return OrderCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_BITMAPCACHE: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_BITMAPCACHE: return BitmapCacheCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_POINTER: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_POINTER: return PointerCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_INPUT: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_INPUT: return InputCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_BRUSH: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_BRUSH: return BrushCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_GLYPHCACHE: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_GLYPHCACHE: return GlyphCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_OFFSCREENCACHE: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_OFFSCREENCACHE: return OffscreenBitmapCacheCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_VIRTUALCHANNEL: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_VIRTUALCHANNEL: return VirtualChannelCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_SOUND: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_SOUND: return SoundCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_CONTROL: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_CONTROL: return ControlCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_ACTIVATION: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_ACTIVATION: return WindowActivationCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_FONT: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_FONT: return FontCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_COLORCACHE: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_COLORCACHE: return ColorCacheCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) - elif self.capabilitySetType == CapsType.CAPSTYPE_SHARE: + elif self.capabilitySetType.value == CapsType.CAPSTYPE_SHARE: return ShareCapability(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) else: return String(readLen = UInt16Le(lambda:self.lengthCapability.value - 4)) @@ -283,12 +274,12 @@ class Capability(CompositeType): self.capability = FactoryType(capability) class GeneralCapability(CompositeType): - ''' + """ General capability (protocol version and compression mode) client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240549.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.osMajorType = UInt16Le() @@ -304,12 +295,12 @@ class GeneralCapability(CompositeType): self.suppressOutputSupport = UInt8() class BitmapCapability(CompositeType): - ''' + """ Bitmap format Capability client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240554.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.preferredBitsPerPixel = UInt16Le() @@ -327,12 +318,12 @@ class BitmapCapability(CompositeType): self.pad2octetsB = UInt16Le() class OrderCapability(CompositeType): - ''' + """ Order capability list all drawing order supported client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240556.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.terminalDescriptor = String("\x00" * 16, readLen = UInt8(16)) @@ -342,8 +333,8 @@ class OrderCapability(CompositeType): self.pad2octetsA = UInt16Le(0) self.maximumOrderLevel = UInt16Le(1) self.numberFonts = UInt16Le() - self.orderFlags = OrderFlag.NEGOTIATEORDERSUPPORT - self.orderSupport = ArrayType(UInt8, init = [UInt8(0) for i in range (0, 32)], readLen = UInt8(32)) + self.orderFlags = UInt16Le(OrderFlag.NEGOTIATEORDERSUPPORT) + self.orderSupport = ArrayType(UInt8, init = [UInt8(0) for _ in range (0, 32)], readLen = UInt8(32)) self.textFlags = UInt16Le() self.orderSupportExFlags = UInt16Le() self.pad4octetsB = UInt32Le() @@ -354,11 +345,11 @@ class OrderCapability(CompositeType): self.pad2octetsE = UInt16Le() class BitmapCacheCapability(CompositeType): - ''' - Order use to cache bitmap very usefull + """ + Order use to cache bitmap very useful client -> server @see: http://msdn.microsoft.com/en-us/library/cc240559.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.pad1 = UInt32Le() @@ -375,13 +366,13 @@ class BitmapCacheCapability(CompositeType): self.cache2MaximumCellSize = UInt16Le() class PointerCapability(CompositeType): - ''' + """ Use to indicate pointer handle of client Paint by server or per client client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240562.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.colorPointerFlag = UInt16Le() @@ -389,12 +380,12 @@ class PointerCapability(CompositeType): self.pointerCacheSize = UInt16Le() class InputCapability(CompositeType): - ''' + """ Use to indicate input capabilities client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240563.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.inputFlags = UInt16Le() @@ -411,69 +402,69 @@ class InputCapability(CompositeType): self.imeFileName = String("\x00" * 64, readLen = UInt8(64)) class BrushCapability(CompositeType): - ''' + """ Use to indicate brush capability client -> server @see: http://msdn.microsoft.com/en-us/library/cc240564.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) - self.brushSupportLevel = BrushSupport.BRUSH_DEFAULT + self.brushSupportLevel = UInt32Le(BrushSupport.BRUSH_DEFAULT) class GlyphCapability(CompositeType): - ''' + """ Use in font order client -> server @see: http://msdn.microsoft.com/en-us/library/cc240565.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) - self.glyphCache = ArrayType(CacheEntry, init = [CacheEntry() for i in range(0,10)], readLen = UInt8(10)) + self.glyphCache = ArrayType(CacheEntry, init = [CacheEntry() for _ in range(0,10)], readLen = UInt8(10)) self.fragCache = UInt32Le() #all fonts are sent with bitmap format (very expensive) - self.glyphSupportLevel = GlyphSupport.GLYPH_SUPPORT_NONE + self.glyphSupportLevel = UInt16Le(GlyphSupport.GLYPH_SUPPORT_NONE) self.pad2octets = UInt16Le() class OffscreenBitmapCacheCapability(CompositeType): - ''' + """ use to cached bitmap in offscreen area client -> server @see: http://msdn.microsoft.com/en-us/library/cc240550.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) - self.offscreenSupportLevel = OffscreenSupportLevel.FALSE + self.offscreenSupportLevel = UInt32Le(OffscreenSupportLevel.FALSE) self.offscreenCacheSize = UInt16Le() self.offscreenCacheEntries = UInt16Le() class VirtualChannelCapability(CompositeType): - ''' + """ use to determine virtual channel compression client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240551.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) - self.flags = VirtualChannelCompressionFlag.VCCAPS_NO_COMPR + self.flags = UInt32Le(VirtualChannelCompressionFlag.VCCAPS_NO_COMPR) self.VCChunkSize = UInt32Le(optional = True) class SoundCapability(CompositeType): - ''' - use to exchange sound capability + """ + Use to exchange sound capability client -> server @see: http://msdn.microsoft.com/en-us/library/cc240552.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) - self.soundFlags = SoundFlag.NONE + self.soundFlags = UInt16Le(SoundFlag.NONE) self.pad2octetsA = UInt16Le() class ControlCapability(CompositeType): - ''' + """ client -> server but server ignore contents! Thanks krosoft for brandwidth @see: http://msdn.microsoft.com/en-us/library/cc240568.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.controlFlags = UInt16Le() @@ -482,10 +473,10 @@ class ControlCapability(CompositeType): self.detachInterest = UInt16Le(0x0002) class WindowActivationCapability(CompositeType): - ''' + """ client -> server but server ignore contents! Thanks krosoft for brandwidth @see: http://msdn.microsoft.com/en-us/library/cc240569.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.helpKeyFlag = UInt16Le() @@ -494,35 +485,35 @@ class WindowActivationCapability(CompositeType): self.windowManagerKeyFlag = UInt16Le() class FontCapability(CompositeType): - ''' - use to indicate font support + """ + Use to indicate font support client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240571.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.fontSupportFlags = UInt16Le(0x0001) self.pad2octets = UInt16Le() class ColorCacheCapability(CompositeType): - ''' + """ client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc241564.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.colorTableCacheSize = UInt16Le(0x0006) self.pad2octets = UInt16Le() class ShareCapability(CompositeType): - ''' - use to advertise channel id of server + """ + Use to advertise channel id of server client -> server server -> client @see: http://msdn.microsoft.com/en-us/library/cc240570.aspx - ''' + """ def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.nodeId = UInt16Le() diff --git a/rdpy/protocol/rdp/gcc.py b/rdpy/protocol/rdp/gcc.py index 580048d..79833cf 100644 --- a/rdpy/protocol/rdp/gcc.py +++ b/rdpy/protocol/rdp/gcc.py @@ -1,9 +1,27 @@ -''' -@author sylvain -@summary gcc language -@see: http://msdn.microsoft.com/en-us/library/cc240508.aspx -''' -from rdpy.network.const import ConstAttributes, TypeAttributes +# +# 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 . +# + +""" +Implement GCC structure use in RDP protocol +http://msdn.microsoft.com/en-us/library/cc240508.aspx +""" + from rdpy.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof import per from rdpy.network.error import InvalidExpectedDataException @@ -12,76 +30,64 @@ t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 ) h221_cs_key = "Duca"; h221_sc_key = "McDn"; -@ConstAttributes -@TypeAttributes(UInt16Le) class ServerToClientMessage(object): - ''' + """ Server to Client block - gcc conference messages + GCC conference messages @see: http://msdn.microsoft.com/en-us/library/cc240509.aspx - ''' + """ SC_CORE = 0x0C01 SC_SECURITY = 0x0C02 SC_NET = 0x0C03 -@ConstAttributes -@TypeAttributes(UInt16Le) class ClientToServerMessage(object): - ''' + """ Client to Server block - gcc conference messages + GCC conference messages @see: http://msdn.microsoft.com/en-us/library/cc240509.aspx - ''' + """ CS_CORE = 0xC001 CS_SECURITY = 0xC002 CS_NET = 0xC003 CS_CLUSTER = 0xC004 CS_MONITOR = 0xC005 -@ConstAttributes -@TypeAttributes(UInt16Le) class ColorDepth(object): - ''' - depth color + """ + Depth color @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ RNS_UD_COLOR_8BPP = 0xCA01 RNS_UD_COLOR_16BPP_555 = 0xCA02 RNS_UD_COLOR_16BPP_565 = 0xCA03 RNS_UD_COLOR_24BPP = 0xCA04 -@ConstAttributes -@TypeAttributes(UInt16Le) class HighColor(object): - ''' - high color of client + """ + High color of client @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ HIGH_COLOR_4BPP = 0x0004 HIGH_COLOR_8BPP = 0x0008 HIGH_COLOR_15BPP = 0x000f HIGH_COLOR_16BPP = 0x0010 HIGH_COLOR_24BPP = 0x0018 -@ConstAttributes -@TypeAttributes(UInt16Le) class Support(object): - ''' - support depth flag + """ + Supported depth flag @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ RNS_UD_24BPP_SUPPORT = 0x0001 RNS_UD_16BPP_SUPPORT = 0x0002 RNS_UD_15BPP_SUPPORT = 0x0004 RNS_UD_32BPP_SUPPORT = 0x0008 -@ConstAttributes -@TypeAttributes(UInt16Le) class CapabilityFlags(object): - ''' - for more details on each flags click above + """ + For more details on each flags click above @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001 RNS_UD_CS_WANT_32BPP_SESSION = 0x0002 RNS_UD_CS_SUPPORT_STATUSINFO_PDU = 0x0004 @@ -94,14 +100,12 @@ class CapabilityFlags(object): RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE = 0x0200 RNS_UD_CS_SUPPORT_HEARTBEAT_PDU = 0x0400 -@ConstAttributes -@TypeAttributes(UInt8) class ConnectionType(object): - ''' - this information is correct if + """ + This information is correct if RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ CONNECTION_TYPE_MODEM = 0x01 CONNECTION_TYPE_BROADBAND_LOW = 0x02 CONNECTION_TYPE_SATELLITE = 0x03 @@ -110,41 +114,33 @@ class ConnectionType(object): CONNECTION_TYPE_LAN = 0x06 CONNECTION_TYPE_AUTODETECT = 0x07 -@ConstAttributes -@TypeAttributes(UInt32Le) class Version(object): - ''' - supported version of RDP + """ + Supported version of RDP @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ RDP_VERSION_4 = 0x00080001 RDP_VERSION_5_PLUS = 0x00080004 -@ConstAttributes -@TypeAttributes(UInt16Le) class Sequence(object): RNS_UD_SAS_DEL = 0xAA03 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class Encryption(object): - ''' - encryption method supported - @deprecated: because rdpy use ssl but need to send to server... + """ + Encryption methods supported + @deprecated: because rdpy use SSL but need to send to server... @see: http://msdn.microsoft.com/en-us/library/cc240511.aspx - ''' + """ ENCRYPTION_FLAG_40BIT = 0x00000001 ENCRYPTION_FLAG_128BIT = 0x00000002 ENCRYPTION_FLAG_56BIT = 0x00000008 FIPS_ENCRYPTION_FLAG = 0x00000010 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class ChannelOptions(object): - ''' - channel options + """ + Channel options @see: http://msdn.microsoft.com/en-us/library/cc240513.aspx - ''' + """ CHANNEL_OPTION_INITIALIZED = 0x80000000 CHANNEL_OPTION_ENCRYPT_RDP = 0x40000000 CHANNEL_OPTION_ENCRYPT_SC = 0x20000000 @@ -156,14 +152,12 @@ class ChannelOptions(object): CHANNEL_OPTION_COMPRESS = 0x00400000 CHANNEL_OPTION_SHOW_PROTOCOL = 0x00200000 REMOTE_CONTROL_PERSISTENT = 0x00100000 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class KeyboardType(object): - ''' + """ Keyboard type IBM_101_102_KEYS is the most common keyboard type - ''' + """ IBM_PC_XT_83_KEY = 0x00000001 OLIVETTI = 0x00000002 IBM_PC_AT_84_KEY = 0x00000003 @@ -171,14 +165,12 @@ class KeyboardType(object): NOKIA_1050 = 0x00000005 NOKIA_9140 = 0x00000006 JAPANESE = 0x00000007 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class KeyboardLayout(object): - ''' + """ Keyboard layout definition @see: http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx - ''' + """ ARABIC = 0x00000401 BULGARIAN = 0x00000402 CHINESE_US_KEYBOARD = 0x00000404 @@ -201,64 +193,64 @@ class KeyboardLayout(object): class ClientCoreSettings(CompositeType): - ''' - class that represent core setting of client + """ + Class that represent core setting of client @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx - ''' + """ def __init__(self): CompositeType.__init__(self) - self.rdpVersion = Version.RDP_VERSION_5_PLUS + self.rdpVersion = UInt32Le(Version.RDP_VERSION_5_PLUS) self.desktopWidth = UInt16Le(1280) self.desktopHeight = UInt16Le(800) - self.colorDepth = ColorDepth.RNS_UD_COLOR_8BPP - self.sasSequence = Sequence.RNS_UD_SAS_DEL - self.kbdLayout = KeyboardLayout.FRENCH + self.colorDepth = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP) + self.sasSequence = UInt16Le(Sequence.RNS_UD_SAS_DEL) + self.kbdLayout = UInt32Le(KeyboardLayout.FRENCH) self.clientBuild = UInt32Le(3790) self.clientName = UniString("rdpy" + "\x00"*11, readLen = UInt8(30)) - self.keyboardType = KeyboardType.IBM_101_102_KEYS + self.keyboardType = UInt32Le(KeyboardType.IBM_101_102_KEYS) self.keyboardSubType = UInt32Le(0) self.keyboardFnKeys = UInt32Le(12) self.imeFileName = String("\x00"*64, readLen = UInt8(64)) - self.postBeta2ColorDepth = ColorDepth.RNS_UD_COLOR_8BPP + self.postBeta2ColorDepth = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP) self.clientProductId = UInt16Le(1) self.serialNumber = UInt32Le(0) - self.highColorDepth = HighColor.HIGH_COLOR_24BPP - self.supportedColorDepths = Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT | Support.RNS_UD_15BPP_SUPPORT - self.earlyCapabilityFlags = CapabilityFlags.RNS_UD_CS_SUPPORT_ERRINFO_PDU + self.highColorDepth = UInt16Le(HighColor.HIGH_COLOR_24BPP) + self.supportedColorDepths = UInt16Le(Support.RNS_UD_32BPP_SUPPORT | Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT) + self.earlyCapabilityFlags = UInt16Le(CapabilityFlags.RNS_UD_CS_SUPPORT_ERRINFO_PDU) self.clientDigProductId = String("\x00"*64, readLen = UInt8(64)) self.connectionType = UInt8() self.pad1octet = UInt8() self.serverSelectedProtocol = UInt32Le() class ServerCoreSettings(CompositeType): - ''' - server side core settings structure + """ + Server side core settings structure @see: http://msdn.microsoft.com/en-us/library/cc240517.aspx - ''' + """ def __init__(self): CompositeType.__init__(self) - self.rdpVersion = Version.RDP_VERSION_5_PLUS + self.rdpVersion = UInt32Le(Version.RDP_VERSION_5_PLUS) self.clientRequestedProtocol = UInt32Le() class ClientSecuritySettings(CompositeType): - ''' - client security setting + """ + Client security setting @deprecated: because we use ssl @see: http://msdn.microsoft.com/en-us/library/cc240511.aspx - ''' + """ def __init__(self): CompositeType.__init__(self) self.encryptionMethods = UInt32Le() self.extEncryptionMethods = UInt32Le() class ServerSecuritySettings(CompositeType): - ''' - server security settings - may be ignore because rdpy don't use + """ + Server security settings + May be ignored because rdpy don't use RDP security level - @deprecated: because we use ssl + @deprecated: because we use SSL @see: http://msdn.microsoft.com/en-us/library/cc240518.aspx - ''' + """ def __init__(self): CompositeType.__init__(self) self.encryptionMethod = UInt32Le() @@ -266,12 +258,11 @@ class ServerSecuritySettings(CompositeType): class ClientRequestedChannel(CompositeType): - ''' - channels structure share between - client and server + """ + Channels structure share between client and server @see: http://msdn.microsoft.com/en-us/library/cc240512.aspx @see: http://msdn.microsoft.com/en-us/library/cc240513.aspx - ''' + """ def __init__(self, name = "", options = UInt32Le()): CompositeType.__init__(self) #name of channel @@ -280,9 +271,9 @@ class ClientRequestedChannel(CompositeType): self.options = options class ClientSettings(object): - ''' - class which group all client settings supported by RDPY - ''' + """ + Class which group all client settings supported by RDPY + """ def __init__(self): self.core = ClientCoreSettings() #list of ClientRequestedChannel read network gcc packet @@ -290,9 +281,9 @@ class ClientSettings(object): self.security = ClientSecuritySettings() class ServerSettings(object): - ''' - server settings - ''' + """ + Server settings + """ def __init__(self): #core settings of server self.core = ServerCoreSettings() @@ -302,11 +293,11 @@ class ServerSettings(object): self.channelsId = [] def writeConferenceCreateRequest(settings): - ''' - write conference create request structure + """ + Write conference create request structure @param settings: ClientSettings - @return: struct that represent - ''' + @return: structure that represent + """ userData = writeClientDataBlocks(settings) userDataStream = Stream() userDataStream.writeType(userData) @@ -318,12 +309,12 @@ def writeConferenceCreateRequest(settings): per.writeOctetStream(h221_cs_key, 4), per.writeOctetStream(userDataStream.getvalue())) def readConferenceCreateResponse(s): - ''' - read response from server + """ + Read response from server and return server settings read from this response @param s: Stream @return: ServerSettings - ''' + """ per.readChoice(s) per.readObjectIdentifier(s, t124_02_98_oid) per.readLength(s) @@ -339,22 +330,22 @@ def readConferenceCreateResponse(s): def writeClientDataBlocks(settings): - ''' - write all blocks for client - and return gcc valid structure + """ + Write all blocks for client + and return GCC valid structure @param settings: ClientSettings - ''' + """ return (writeClientCoreData(settings.core), writeClientSecurityData(settings.security), writeClientNetworkData(settings.networkChannels)) def readServerDataBlocks(s): - ''' - read gcc server data blocks - and return result in Server Settings object + """ + Read GCC server data blocks + And return result in Server Settings object @param s: Stream @return: ServerSettings - ''' + """ settings = ServerSettings() length = per.readLength(s) while length > 0: @@ -363,61 +354,61 @@ def readServerDataBlocks(s): blockLength = UInt16Le() s.readType((blockType, blockLength)) #read core block - if blockType == ServerToClientMessage.SC_CORE: + if blockType.value == ServerToClientMessage.SC_CORE: s.readType(settings.core) #read network block - elif blockType == ServerToClientMessage.SC_NET: + elif blockType.value == ServerToClientMessage.SC_NET: settings.channelsId = readServerSecurityData(s) #read security block #unused in rdpy because use SSL layer - elif blockType == ServerToClientMessage.SC_SECURITY: + elif blockType.value == ServerToClientMessage.SC_SECURITY: s.readType(settings.security) else: - print "Unknow server block %s"%hex(type) + print "Unknown server block %s"%hex(type) length -= blockLength.value s.seek(marker + blockLength.value) return settings def writeClientCoreData(core): - ''' - write client settings in GCC language + """ + Write client settings in GCC language @param settings: ClientSettings structure @return: structure that represent client data blocks - ''' - return (ClientToServerMessage.CS_CORE, UInt16Le(sizeof(core) + 4), core) + """ + return (UInt16Le(ClientToServerMessage.CS_CORE), UInt16Le(sizeof(core) + 4), core) def writeClientSecurityData(security): - ''' - write security header block and security structure + """ + Write security header block and security structure @param security: ClientSecuritySettings - @return: gcc client security data - ''' - return (ClientToServerMessage.CS_SECURITY, UInt16Le(sizeof(security) + 4), security) + @return: GCC client security data + """ + return (UInt16Le(ClientToServerMessage.CS_SECURITY), UInt16Le(sizeof(security) + 4), security) def writeClientNetworkData(channels): - ''' - write network packet whith channels infos + """ + Write network packet with channels infos @param channels: list of ClientRequestedChannel - @return: gcc network packet - ''' + @return: GCC network packet + """ if len(channels) == 0: return () - return (ClientToServerMessage.CS_NET, UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 8), UInt32Le(len(channels)), tuple(channels)) + return (UInt16Le(ClientToServerMessage.CS_NET), UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 8), UInt32Le(len(channels)), tuple(channels)) def readServerSecurityData(s): - ''' - read server security and fill it in settings - read all channels accepted by server by server + """ + Read server security and fill it in settings + Read all channels accepted by server by server @param s: Stream @return: list of channel id selected by server @see: http://msdn.microsoft.com/en-us/library/cc240522.aspx - ''' + """ channelsId = [] channelId = UInt16Le() numberOfChannels = UInt16Le() s.readType((channelId, numberOfChannels)) - for i in range(0, numberOfChannels.value): + for _ in range(0, numberOfChannels.value): channelId = UInt16Le() s.readType(channelId) channelsId.append(channelId) diff --git a/rdpy/protocol/rdp/mcs.py b/rdpy/protocol/rdp/mcs.py index 1c95d36..8064e14 100644 --- a/rdpy/protocol/rdp/mcs.py +++ b/rdpy/protocol/rdp/mcs.py @@ -165,7 +165,7 @@ class MCS(LayerAutomata): self.writeDomainParams(1, 1, 1, 0x420), self.writeDomainParams(0xffff, 0xfc17, 0xffff, 0xffff), ber.writeOctetstring(ccReqStream.getvalue())) - self._transport.send((ber.writeApplicationTag(UInt8(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) diff --git a/rdpy/protocol/rdp/pdu.py b/rdpy/protocol/rdp/pdu.py index cae96c3..e4a5e88 100644 --- a/rdpy/protocol/rdp/pdu.py +++ b/rdpy/protocol/rdp/pdu.py @@ -25,13 +25,10 @@ In this layer are managed all mains bitmap update orders end user inputs from rdpy.network.layer import LayerAutomata from rdpy.network.type import CompositeType, UniString, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType -from rdpy.network.const import ConstAttributes, TypeAttributes from rdpy.network.error import InvalidExpectedDataException, ErrorReportedFromPeer import gcc, lic, caps -@ConstAttributes -@TypeAttributes(UInt16Le) class SecurityFlag(object): """ Microsoft security flags @@ -39,8 +36,6 @@ class SecurityFlag(object): SEC_INFO_PKT = 0x0040 SEC_LICENSE_PKT = 0x0080 -@ConstAttributes -@TypeAttributes(UInt32Le) class InfoFlag(object): """ Client capabilities informations @@ -65,8 +60,6 @@ class InfoFlag(object): INFO_VIDEO_DISABLE = 0x00400000 INFO_CompressionTypeMask = 0x00001E00 -@ConstAttributes -@TypeAttributes(UInt32Le) class PerfFlag(object): """ Network performances flag @@ -80,17 +73,13 @@ class PerfFlag(object): PERF_ENABLE_FONT_SMOOTHING = 0x00000080 PERF_ENABLE_DESKTOP_COMPOSITION = 0x00000100 -@ConstAttributes -@TypeAttributes(UInt16Le) class AfInet(object): """ IPv4 or IPv6 adress style """ AF_INET = 0x00002 AF_INET6 = 0x0017 - -@ConstAttributes -@TypeAttributes(UInt16Le) + class PDUType(object): """ Data PDU type primary index @@ -101,9 +90,7 @@ class PDUType(object): PDUTYPE_DEACTIVATEALLPDU = 0x16 PDUTYPE_DATAPDU = 0x17 PDUTYPE_SERVER_REDIR_PKT = 0x1A - -@ConstAttributes -@TypeAttributes(UInt8) + class PDUType2(object): """ Data PDU type secondary index @@ -133,9 +120,7 @@ class PDUType2(object): PDUTYPE2_ARC_STATUS_PDU = 0x32 PDUTYPE2_STATUS_INFO_PDU = 0x36 PDUTYPE2_MONITOR_LAYOUT_PDU = 0x37 - -@ConstAttributes -@TypeAttributes(UInt8) + class StreamId(object): """ Stream priority @@ -145,9 +130,7 @@ class StreamId(object): STREAM_LOW = 0x01 STREAM_MED = 0x02 STREAM_HI = 0x04 - -@ConstAttributes -@TypeAttributes(UInt8) + class CompressionOrder(object): """ PDU compression order @@ -158,8 +141,6 @@ class CompressionOrder(object): PACKET_AT_FRONT = 0x40 PACKET_FLUSHED = 0x80 -@ConstAttributes -@TypeAttributes(UInt8) class CompressionType(object): """ PDU compression type @@ -170,8 +151,6 @@ class CompressionType(object): PACKET_COMPR_TYPE_RDP6 = 0x2 PACKET_COMPR_TYPE_RDP61 = 0x3 -@ConstAttributes -@TypeAttributes(UInt16Le) class Action(object): """ Action flag use in Control PDU packet @@ -182,8 +161,6 @@ class Action(object): CTRLACTION_DETACH = 0x0003 CTRLACTION_COOPERATE = 0x0004 -@ConstAttributes -@TypeAttributes(UInt16Le) class PersistentKeyListFlag(object): """ Use to determine the number of persistent key packet @@ -192,8 +169,6 @@ class PersistentKeyListFlag(object): PERSIST_FIRST_PDU = 0x01 PERSIST_LAST_PDU = 0x02 -@ConstAttributes -@TypeAttributes(UInt16Le) class BitmapFlag(object): """ Use in bitmap update PDU @@ -201,9 +176,7 @@ class BitmapFlag(object): """ BITMAP_COMPRESSION = 0x0001 NO_BITMAP_COMPRESSION_HDR = 0x0400 - -@ConstAttributes -@TypeAttributes(UInt16Le) + class UpdateType(object): """ Use in update PDU to determine which type of update @@ -213,9 +186,7 @@ class UpdateType(object): UPDATETYPE_BITMAP = 0x0001 UPDATETYPE_PALETTE = 0x0002 UPDATETYPE_SYNCHRONIZE = 0x0003 - -@ConstAttributes -@TypeAttributes(UInt32Le) + class ErrorInfo(object): """ Error code use in Error info PDU @@ -438,7 +409,7 @@ class RDPInfo(CompositeType): #code page self.codePage = UInt32Le() #support flag - self.flag = InfoFlag.INFO_MOUSE | InfoFlag.INFO_UNICODE | InfoFlag.INFO_LOGONERRORS | InfoFlag.INFO_LOGONNOTIFY | InfoFlag.INFO_ENABLEWINDOWSKEY | InfoFlag.INFO_DISABLECTRLALTDEL + self.flag = UInt32Le(InfoFlag.INFO_MOUSE | InfoFlag.INFO_UNICODE | InfoFlag.INFO_LOGONERRORS | InfoFlag.INFO_LOGONNOTIFY | InfoFlag.INFO_ENABLEWINDOWSKEY | InfoFlag.INFO_DISABLECTRLALTDEL) self.cbDomain = UInt16Le(lambda:sizeof(self.domain) - 2) self.cbUserName = UInt16Le(lambda:sizeof(self.userName) - 2) self.cbPassword = UInt16Le(lambda:sizeof(self.password) - 2) @@ -461,13 +432,13 @@ class RDPExtendedInfo(CompositeType): """ def __init__(self, conditional): CompositeType.__init__(self, conditional = conditional) - self.clientAddressFamily = AfInet.AF_INET + self.clientAddressFamily = UInt16Le(AfInet.AF_INET) self.cbClientAddress = UInt16Le(lambda:sizeof(self.clientAddress)) self.clientAddress = UniString(readLen = self.cbClientAddress) self.cbClientDir = UInt16Le(lambda:sizeof(self.clientDir)) self.clientDir = UniString(readLen = self.cbClientDir) #TODO make tiomezone - #self.performanceFlags = PerfFlag.PERF_DISABLE_WALLPAPER | PerfFlag.PERF_DISABLE_MENUANIMATIONS | PerfFlag.PERF_DISABLE_CURSOR_SHADOW + #self.performanceFlags = UInt32Le(PerfFlag.PERF_DISABLE_WALLPAPER | PerfFlag.PERF_DISABLE_MENUANIMATIONS | PerfFlag.PERF_DISABLE_CURSOR_SHADOW) class ShareControlHeader(CompositeType): """ @@ -475,29 +446,29 @@ class ShareControlHeader(CompositeType): @see: http://msdn.microsoft.com/en-us/library/cc240576.aspx """ def __init__(self, totalLength, pduType, userId): - ''' - constructor + """ + Set pduType as constant @param totalLength: total length of pdu packet - ''' + """ CompositeType.__init__(self) #share control header self.totalLength = UInt16Le(totalLength) - self.pduType = UInt16Le(pduType.value, constant = True) - self.PDUSource = UInt16Le(userId.value + 1001) + self.pduType = UInt16Le(pduType, constant = True) + self.PDUSource = UInt16Le(userId + 1001) class ShareDataHeader(CompositeType): """ PDU share data header @see: http://msdn.microsoft.com/en-us/library/cc240577.aspx """ - def __init__(self, size, pduType2 = None, userId = UInt16Le(), shareId = UInt32Le()): + def __init__(self, size, pduType2 = None, userId = 0, shareId = 0): CompositeType.__init__(self) self.shareControlHeader = ShareControlHeader(size, PDUType.PDUTYPE_DATAPDU, userId) - self.shareId = shareId + self.shareId = UInt32Le(shareId) self.pad1 = UInt8() - self.streamId = StreamId.STREAM_LOW + self.streamId = UInt8(StreamId.STREAM_LOW) self.uncompressedLength = UInt16Le(lambda:(UInt16Le(size).value - 14)) - self.pduType2 = UInt8() if pduType2 is None else UInt8(pduType2.value, constant = True) + self.pduType2 = UInt8() if pduType2 is None else UInt8(pduType2, constant = True) self.compressedType = UInt8() self.compressedLength = UInt16Le() @@ -506,7 +477,7 @@ class DemandActivePDU(CompositeType): @see: http://msdn.microsoft.com/en-us/library/cc240485.aspx Main use for capabilities exchange server -> client """ - def __init__(self, userId = UInt16Le()): + def __init__(self, userId = 0): CompositeType.__init__(self) self.shareControlHeader = ShareControlHeader(lambda:sizeof(self), PDUType.PDUTYPE_DEMANDACTIVEPDU, userId) self.shareId = UInt32Le() @@ -523,7 +494,7 @@ class ConfirmActivePDU(CompositeType): @see: http://msdn.microsoft.com/en-us/library/cc240488.aspx Main use for capabilities confirm client -> sever """ - def __init__(self, userId = UInt16Le()): + def __init__(self, userId = 0): CompositeType.__init__(self) self.shareControlHeader = ShareControlHeader(lambda:sizeof(self), PDUType.PDUTYPE_CONFIRMACTIVEPDU, userId) self.shareId = UInt32Le() @@ -551,7 +522,7 @@ class PersistentListPDU(CompositeType): Fill with some keys from previous session @see: http://msdn.microsoft.com/en-us/library/cc240495.aspx """ - def __init__(self, userId = UInt16Le(), shareId = UInt32Le()): + def __init__(self, userId = 0, shareId = 0): CompositeType.__init__(self) self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), PDUType2.PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST, userId, shareId) self.numEntriesCache0 = UInt16Le() @@ -573,22 +544,22 @@ class DataPDU(CompositeType): """ Generic pdu packet use after connection sequence """ - def __init__(self, pduType = None, pduData = None, userId = UInt16Le(), shareId = UInt32Le()): + def __init__(self, pduType = None, pduData = None, userId = 0, shareId = 0): CompositeType.__init__(self) self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), pduType, userId, shareId) def PDUDataFactory(): - if self.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_UPDATE: + if self.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_UPDATE: return UpdateDataPDU() - elif self.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_SYNCHRONIZE: + elif self.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_SYNCHRONIZE: return SynchronizeDataPDU() - elif self.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_CONTROL: + elif self.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_CONTROL: return ControlDataPDU() - elif self.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU: + elif self.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU: return ErrorInfoDataPDU() - elif self.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_FONTLIST: + elif self.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_FONTLIST: return FontListDataPDU() - elif self.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_FONTMAP: + elif self.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_FONTMAP: return FontMapDataPDU() else: #read all value @@ -614,7 +585,7 @@ class ControlDataPDU(CompositeType): """ def __init__(self, action = None): CompositeType.__init__(self) - self.action = UInt16Le(action.value, constant = True) if not action is None else UInt16Le() + self.action = UInt16Le(action, constant = True) if not action is None else UInt16Le() self.grantId = UInt16Le() self.controlId = UInt32Le() @@ -665,7 +636,7 @@ class UpdateDataPDU(CompositeType): self.updateType = updateType def UpdateDataFactory(): - if self.updateType == UpdateType.UPDATETYPE_BITMAP: + if self.updateType.value == UpdateType.UPDATETYPE_BITMAP: return BitmapUpdateDataPDU() else: String() @@ -673,7 +644,7 @@ class UpdateDataPDU(CompositeType): if updateData is None: updateData = UpdateDataFactory - self.updateData = FactoryType(updateData, conditional = lambda:(self.updateType != UpdateType.UPDATETYPE_SYNCHRONIZE)) + self.updateData = FactoryType(updateData, conditional = lambda:(self.updateType.value != UpdateType.UPDATETYPE_SYNCHRONIZE)) class BitmapUpdateDataPDU(CompositeType): """ @@ -684,6 +655,18 @@ class BitmapUpdateDataPDU(CompositeType): CompositeType.__init__(self) self.numberRectangles = UInt16Le() self.rectangles = ArrayType(BitmapData, readLen = self.numberRectangles) + +class ClientInputEventPDU(CompositeType): + """ + PDU use to send client inputs in slow path mode + @see: http://msdn.microsoft.com/en-us/library/cc746160.aspx + """ + def __init__(self, userId = 0, shareId = 0): + CompositeType.__init__(self) + self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), PDUType2.PDUTYPE2_INPUT, userId, shareId) + self.numEvents = UInt16Le() + self.pad2Octets = UInt16Le() + class BitmapCompressedDataHeader(CompositeType): """ @@ -714,8 +697,8 @@ class BitmapData(CompositeType): self.bitsPerPixel = UInt16Le() self.flags = UInt16Le() self.bitmapLength = UInt16Le() - self.bitmapComprHdr = BitmapCompressedDataHeader(conditional = lambda:(not (self.flags | BitmapFlag.NO_BITMAP_COMPRESSION_HDR))) - self.bitmapDataStream = String(readLen = UInt16Le(lambda:(self.bitmapLength.value if (self.flags | BitmapFlag.NO_BITMAP_COMPRESSION_HDR) else self.bitmapComprHdr.cbCompMainBodySize.value))) + self.bitmapComprHdr = BitmapCompressedDataHeader(conditional = lambda:(not (self.flags.value | BitmapFlag.NO_BITMAP_COMPRESSION_HDR))) + self.bitmapDataStream = String(readLen = UInt16Le(lambda:(self.bitmapLength.value if (self.flags.value | BitmapFlag.NO_BITMAP_COMPRESSION_HDR) else self.bitmapComprHdr.cbCompMainBodySize.value))) class PDU(LayerAutomata): """ @@ -729,7 +712,7 @@ class PDU(LayerAutomata): """ LayerAutomata.__init__(self, mode, None) #logon info send from client to server - self._info = RDPInfo(extendedInfoConditional = lambda:self._transport.getGCCServerSettings().core.rdpVersion == gcc.Version.RDP_VERSION_5_PLUS) + self._info = RDPInfo(extendedInfoConditional = lambda:self._transport.getGCCServerSettings().core.rdpVersion.value == gcc.Version.RDP_VERSION_5_PLUS) #server capabilities self._serverCapabilities = { caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.CapsType.CAPSTYPE_GENERAL, caps.GeneralCapability()), @@ -762,7 +745,7 @@ class PDU(LayerAutomata): #caps.CapsType.CAPSTYPE_SHARE : caps.Capability(CapsType.CAPSTYPE_SHARE, caps.ShareCapability()) } #share id between client and server - self._shareId = UInt32Le() + self._shareId = 0 #rdp controller self._controller = controller @@ -780,14 +763,14 @@ class PDU(LayerAutomata): """ Send PDU close packet and call close method on transport method """ - self._transport.send(ShareDataHeader(PDUType2.PDUTYPE2_SHUTDOWN_REQUEST, UInt16Le(self._transport.getUserId()), self._shareId)) + self._transport.send(ShareDataHeader(PDUType2.PDUTYPE2_SHUTDOWN_REQUEST, self._transport.getUserId(), self._shareId)) def sendInfoPkt(self): """ Send a logon info packet """ - #always send extended info because rdpy only accept rdp version 5 and more - self._transport.send((SecurityFlag.SEC_INFO_PKT, UInt16Le(), self._info)) + #always send extended info because rdpy only accept RDP version 5 and more + self._transport.send((UInt16Le(SecurityFlag.SEC_INFO_PKT), UInt16Le(), self._info)) def recvLicenceInfo(self, data): """ @@ -798,7 +781,7 @@ class PDU(LayerAutomata): securityFlagHi = UInt16Le() data.readType((securityFlag, securityFlagHi)) - if securityFlag & SecurityFlag.SEC_LICENSE_PKT != SecurityFlag.SEC_LICENSE_PKT: + if securityFlag.value & SecurityFlag.SEC_LICENSE_PKT != SecurityFlag.SEC_LICENSE_PKT: raise InvalidExpectedDataException("Waiting license packet") validClientPdu = lic.LicPacket() @@ -821,7 +804,7 @@ class PDU(LayerAutomata): #maybe an error message dataPDU = DataPDU() data.readType(dataPDU) - if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU: + if dataPDU.shareDataHeader.pduType2.value != PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU: return dataPDU message = "Unknown code %s"%hex(dataPDU.pduData._value.errorInfo.value) @@ -842,7 +825,7 @@ class PDU(LayerAutomata): demandActivePDU = DemandActivePDU() data.readType(demandActivePDU) - self._shareId = demandActivePDU.shareId + self._shareId = demandActivePDU.shareId.value for cap in demandActivePDU.capabilitySets._array: self._serverCapabilities[cap.capabilitySetType] = cap @@ -855,7 +838,7 @@ class PDU(LayerAutomata): @param data: Stream from transport layer """ dataPDU = self.readDataPDU(data) - if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SYNCHRONIZE: + if dataPDU.shareDataHeader.pduType2.value != PDUType2.PDUTYPE2_SYNCHRONIZE: raise InvalidExpectedDataException("Error in PDU layer automata : expected synchronizePDU") self.setNextState(self.recvServerControlCooperatePDU) @@ -865,7 +848,7 @@ class PDU(LayerAutomata): @param data: Stream from transport layer """ dataPDU = self.readDataPDU(data) - if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action != Action.CTRLACTION_COOPERATE: + if dataPDU.shareDataHeader.pduType2.value != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action.value != Action.CTRLACTION_COOPERATE: raise InvalidExpectedDataException("Error in PDU layer automata : expected controlCooperatePDU") self.setNextState(self.recvServerControlGrantedPDU) @@ -875,7 +858,7 @@ class PDU(LayerAutomata): @param data: Stream from transport layer """ dataPDU = self.readDataPDU(data) - if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action != Action.CTRLACTION_GRANTED_CONTROL: + if dataPDU.shareDataHeader.pduType2.value != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action.value != Action.CTRLACTION_GRANTED_CONTROL: raise InvalidExpectedDataException("Error in PDU layer automata : expected controlGrantedPDU") self.setNextState(self.recvServerFontMapPDU) @@ -885,7 +868,7 @@ class PDU(LayerAutomata): @param data: Stream from transport layer """ dataPDU = self.readDataPDU(data) - if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_FONTMAP: + if dataPDU.shareDataHeader.pduType2.value != PDUType2.PDUTYPE2_FONTMAP: raise InvalidExpectedDataException("Error in PDU layer automata : expected fontMapPDU") print "client is now connected" if not self._presentation is None: @@ -898,7 +881,7 @@ class PDU(LayerAutomata): @param data: Stream from transport layer """ dataPDU = self.readDataPDU(data) - if dataPDU.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_UPDATE and dataPDU.pduData._value.updateType == UpdateType.UPDATETYPE_BITMAP: + if dataPDU.shareDataHeader.pduType2.value == PDUType2.PDUTYPE2_UPDATE and dataPDU.pduData._value.updateType.value == UpdateType.UPDATETYPE_BITMAP: self._controller.recvBitmapUpdateDataPDU(dataPDU.pduData._value.updateData._value) @@ -908,9 +891,9 @@ class PDU(LayerAutomata): """ #init general capability generalCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability._value - generalCapability.osMajorType = caps.MajorType.OSMAJORTYPE_WINDOWS - generalCapability.osMinorType = caps.MinorType.OSMINORTYPE_WINDOWS_NT - generalCapability.extraFlags = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR + generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS + generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT + generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR #init bitmap capability bitmapCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_BITMAP].capability._value @@ -920,11 +903,11 @@ class PDU(LayerAutomata): #init order capability orderCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_ORDER].capability._value - orderCapability.orderFlags |= caps.OrderFlag.ZEROBOUNDSDELTASSUPPORT + orderCapability.orderFlags.value |= caps.OrderFlag.ZEROBOUNDSDELTASSUPPORT #init input capability inputCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_INPUT].capability._value - inputCapability.inputFlags = caps.InputFlags.INPUT_FLAG_SCANCODES | caps.InputFlags.INPUT_FLAG_MOUSEX | caps.InputFlags.INPUT_FLAG_UNICODE + inputCapability.inputFlags.value = caps.InputFlags.INPUT_FLAG_SCANCODES | caps.InputFlags.INPUT_FLAG_MOUSEX | caps.InputFlags.INPUT_FLAG_UNICODE inputCapability.keyboardLayout = self._transport.getGCCClientSettings().core.kbdLayout inputCapability.keyboardType = self._transport.getGCCClientSettings().core.keyboardType inputCapability.keyboardSubType = self._transport.getGCCClientSettings().core.keyboardSubType @@ -932,8 +915,8 @@ class PDU(LayerAutomata): inputCapability.imeFileName = self._transport.getGCCClientSettings().core.imeFileName #make active PDU packet - confirmActivePDU = ConfirmActivePDU(UInt16Le(self._transport.getUserId())) - confirmActivePDU.shareId = self._shareId + confirmActivePDU = ConfirmActivePDU(self._transport.getUserId()) + confirmActivePDU.shareId.value = self._shareId confirmActivePDU.capabilitySets._array = self._clientCapabilities.values() self._transport.send(confirmActivePDU) #send synchronize @@ -943,24 +926,24 @@ class PDU(LayerAutomata): """ send a synchronize PDU from client to server """ - synchronizePDU = DataPDU(PDUType2.PDUTYPE2_SYNCHRONIZE, SynchronizeDataPDU(UInt16Le(self._transport.getChannelId())), UInt16Le(self._transport.getUserId()), self._shareId) + synchronizePDU = DataPDU(PDUType2.PDUTYPE2_SYNCHRONIZE, SynchronizeDataPDU(UInt16Le(self._transport.getChannelId())), self._transport.getUserId(), self._shareId) self._transport.send(synchronizePDU) #ask for cooperation - controlCooperatePDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_COOPERATE), UInt16Le(self._transport.getUserId()), self._shareId) + controlCooperatePDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_COOPERATE), self._transport.getUserId(), self._shareId) self._transport.send(controlCooperatePDU) #request control - controlRequestPDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_REQUEST_CONTROL), UInt16Le(self._transport.getUserId()), self._shareId) + controlRequestPDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_REQUEST_CONTROL), self._transport.getUserId(), self._shareId) self._transport.send(controlRequestPDU) #send persistent list pdu I don't know why this packet is rejected maybe beacause we made a 0 size bitmapcache capability #persistentListPDU = PersistentListPDU(self._transport.getUserId(), self._shareId) - #persistentListPDU.bitMask = PersistentKeyListFlag.PERSIST_FIRST_PDU | PersistentKeyListFlag.PERSIST_LAST_PDU + #persistentListPDU.bitMask = UInt16Le(PersistentKeyListFlag.PERSIST_FIRST_PDU | PersistentKeyListFlag.PERSIST_LAST_PDU) #self._transport.send(persistentListPDU) #deprecated font list pdu - fontListPDU = DataPDU(PDUType2.PDUTYPE2_FONTLIST, FontListDataPDU(), UInt16Le(self._transport.getUserId()), self._shareId) + fontListPDU = DataPDU(PDUType2.PDUTYPE2_FONTLIST, FontListDataPDU(), self._transport.getUserId(), self._shareId) self._transport.send(fontListPDU) self.setNextState(self.recvServerSynchronizePDU) diff --git a/rdpy/protocol/rdp/rdp.py b/rdpy/protocol/rdp/rdp.py index 696cb95..68fb609 100644 --- a/rdpy/protocol/rdp/rdp.py +++ b/rdpy/protocol/rdp/rdp.py @@ -42,7 +42,7 @@ class RDPController(object): for observer in self._clientObserver: #for each rectangle in update PDU for rectangle in bitmapUpdateData.rectangles._array: - observer.onBitmapUpdate(rectangle.destLeft.value, rectangle.destTop.value, rectangle.destRight.value, rectangle.destBottom.value, rectangle.width.value, rectangle.height.value, rectangle.bitsPerPixel.value, (rectangle.flags & pdu.BitmapFlag.BITMAP_COMPRESSION).value, rectangle.bitmapDataStream.value) + observer.onBitmapUpdate(rectangle.destLeft.value, rectangle.destTop.value, rectangle.destRight.value, rectangle.destBottom.value, rectangle.width.value, rectangle.height.value, rectangle.bitsPerPixel.value, rectangle.flags.value & pdu.BitmapFlag.BITMAP_COMPRESSION, rectangle.bitmapDataStream.value) class ClientFactory(protocol.Factory): """ @@ -106,7 +106,7 @@ class ServerFactory(protocol.Factory): class RDPClientObserver(object): ''' - class use to inform all rdp event handle by RDPY + class use to inform all RDP event handle by RDPY ''' def __init__(self, controller): """ diff --git a/rdpy/protocol/rfb/rfb.py b/rdpy/protocol/rfb/rfb.py index 8600cf6..62d467c 100644 --- a/rdpy/protocol/rfb/rfb.py +++ b/rdpy/protocol/rfb/rfb.py @@ -29,11 +29,8 @@ 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.const import ConstAttributes, TypeAttributes -from rdpy.network.error import InvalidValue, CallPureVirtualFuntion +from rdpy.network.error import InvalidValue, CallPureVirtualFuntion, InvalidType -@ConstAttributes -@TypeAttributes(String) class ProtocolVersion(object): """ Different protocol version @@ -43,8 +40,6 @@ class ProtocolVersion(object): RFB003007 = "RFB 003.007\n" RFB003008 = "RFB 003.008\n" -@ConstAttributes -@TypeAttributes(UInt8) class SecurityType(object): """ Security type supported @@ -53,8 +48,6 @@ class SecurityType(object): NONE = 1 VNC = 2 -@ConstAttributes -@TypeAttributes(UInt32Be) class Pointer(object): """ Mouse event code (which button) @@ -64,17 +57,13 @@ class Pointer(object): BUTTON1 = 0x1 BUTTON2 = 0x2 BUTTON3 = 0x4 - -@ConstAttributes -@TypeAttributes(SInt32Be) + class Encoding(object): """ Encoding types of FrameBuffer update """ RAW = 0 -@ConstAttributes -@TypeAttributes(UInt8) class ClientToServerMessages(object): """ Client to server messages types @@ -179,18 +168,24 @@ class RFB(RawLayer): """ Implement RFB protocol """ - def __init__(self, mode, controller): + def __init__(self, listener): """ @param mode: LayerMode client or server @param controller: controller use to inform new orders """ + mode = None + if isinstance(listener, RFBClientListener): + mode = LayerMode.CLIENT + else: + raise InvalidType("RFB Layer expect RFBClientListener as listener") + RawLayer.__init__(self, mode) #useful for RFB protocol self._callbackBody = None #protocol version negotiated - self._version = ProtocolVersion.RFB003008 + self._version = String(ProtocolVersion.RFB003008) #number security launch by server - self._securityLevel = SecurityType.INVALID + self._securityLevel = UInt8(SecurityType.INVALID) #shared FrameBuffer client init message self._sharedFlag = UInt8(False) #server init message @@ -205,7 +200,9 @@ class RFB(RawLayer): #current rectangle header self._currentRect = Rectangle() #client or server adaptor - self._controller = controller + self._listener = listener + #ready to send events + self._ready = False def expectWithHeader(self, expectedHeaderLen, callbackBody): """ @@ -255,8 +252,8 @@ class RFB(RawLayer): @param data: Stream may contain protocol version string (ProtocolVersion) """ data.readType(self._version) - if not self._version in [ProtocolVersion.RFB003003, ProtocolVersion.RFB003007, ProtocolVersion.RFB003008]: - self._version = ProtocolVersion.UNKNOWN + if not self._version.value in [ProtocolVersion.RFB003003, ProtocolVersion.RFB003007, ProtocolVersion.RFB003008]: + self._version.value = ProtocolVersion.UNKNOWN def recvProtocolVersion(self, data): """ @@ -266,15 +263,15 @@ class RFB(RawLayer): @param data: Stream """ self.readProtocolVersion(data) - if self._version == ProtocolVersion.UNKNOWN: + if self._version.value == ProtocolVersion.UNKNOWN: print "Unknown protocol version %s send 003.008"%data.getvalue() #protocol version is unknown try best version we can handle - self._version = ProtocolVersion.RFB003008 + self._version.value = ProtocolVersion.RFB003008 #send same version of self.send(self._version) #next state read security - if self._version == ProtocolVersion.RFB003003: + if self._version.value == ProtocolVersion.RFB003003: self.expect(4, self.recvSecurityServer) else: self.expectWithHeader(1, self.recvSecurityList) @@ -300,7 +297,7 @@ class RFB(RawLayer): securityList.append(securityElement) #select high security level for s in securityList: - if s in [SecurityType.NONE, SecurityType.VNC] and s > self._securityLevel: + if s.value in [SecurityType.NONE, SecurityType.VNC] and s > self._securityLevel: self._securityLevel = s break #send back security level choosen @@ -317,7 +314,7 @@ class RFB(RawLayer): data.readType(result) if result == UInt32Be(1): print "Authentification failed" - if self._version == ProtocolVersion.RFB003008: + if self._version.value == ProtocolVersion.RFB003008: self.expectWithHeader(4, self.recvSecurityFailed) else: print "Authentification OK" @@ -352,6 +349,9 @@ class RFB(RawLayer): self.sendSetEncoding() #request entire zone self.sendFramebufferUpdateRequest(False, 0, 0, self._serverInit.width.value, self._serverInit.height.value) + #now i'm ready to send event + self._ready = True; + self.expect(1, self.recvServerOrder) def recvServerOrder(self, data): @@ -382,7 +382,7 @@ class RFB(RawLayer): @param data: Stream that contains well formed packet """ data.readType(self._currentRect) - if self._currentRect.encoding == Encoding.RAW: + if self._currentRect.encoding.value == Encoding.RAW: self.expect(self._currentRect.width.value * self._currentRect.height.value * (self._pixelFormat.BitsPerPixel.value / 8), self.recvRectBody) def recvRectBody(self, data): @@ -390,7 +390,7 @@ class RFB(RawLayer): Read body of rectangle update @param data: Stream that contains well formed packet """ - self._controller.recvRectangle(self._currentRect, self._pixelFormat, data.getvalue()) + self._listener.recvRectangle(self._currentRect, self._pixelFormat, data.getvalue()) self._nbRect = self._nbRect - 1 #if there is another rect to read @@ -414,43 +414,58 @@ class RFB(RawLayer): Very important packet that inform the image struct supported by the client @param pixelFormat: PixelFormat struct """ - self.send((ClientToServerMessages.PIXEL_FORMAT, UInt16Be(), UInt8(), pixelFormat)) + self.send((UInt8(ClientToServerMessages.PIXEL_FORMAT), UInt16Be(), UInt8(), pixelFormat)) def sendSetEncoding(self): """ Send set encoding packet Actually only RAW bitmap encoding are used """ - self.send((ClientToServerMessages.ENCODING, UInt8(), UInt16Be(1), Encoding.RAW)) + self.send((UInt8(ClientToServerMessages.ENCODING), UInt8(), UInt16Be(1), SInt32Be(Encoding.RAW))) def sendFramebufferUpdateRequest(self, incremental, x, y, width, height): """ Request server the specified zone incremental means request only change before last update """ - self.send((ClientToServerMessages.FRAME_BUFFER_UPDATE_REQUEST, FrameBufferUpdateRequest(incremental, x, y, width, height))) + self.send((UInt8(ClientToServerMessages.FRAME_BUFFER_UPDATE_REQUEST), FrameBufferUpdateRequest(incremental, x, y, width, height))) def sendKeyEvent(self, keyEvent): """ Write key event packet @param keyEvent: KeyEvent struct to send """ - self.send((ClientToServerMessages.KEY_EVENT, keyEvent)) + self.send((UInt8(ClientToServerMessages.KEY_EVENT), keyEvent)) def sendPointerEvent(self, pointerEvent): """ Write pointer event packet @param pointerEvent: PointerEvent struct use """ - self.send((ClientToServerMessages.POINTER_EVENT, pointerEvent)) + self.send((UInt8(ClientToServerMessages.POINTER_EVENT), pointerEvent)) def sendClientCutText(self, text): """ write client cut text event packet """ - self.send((ClientToServerMessages.CUT_TEXT, ClientCutText(text))) + self.send((UInt8(ClientToServerMessages.CUT_TEXT), ClientCutText(text))) -class RFBController(object): +class RFBClientListener(object): + """ + Interface use to expose event receive from RFB layer + """ + def recvRectangle(self, rectangle, pixelFormat, data): + """ + Receive rectangle order + Main update order type + @param rectangle: Rectangle type header of packet + @param pixelFormat: pixelFormat struct of current session + @param data: image data + """ + raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recvRectangle", "RFBListener")) + + +class RFBController(RFBClientListener): """ Class use to manage RFB order and dispatch throw observers """ @@ -460,7 +475,7 @@ class RFBController(object): """ self._clientObservers = [] #rfb layer to send client orders - self._rfbLayer = RFB(mode, self) + self._rfbLayer = RFB(self) def getRFBLayer(self): """ @@ -493,6 +508,9 @@ class RFBController(object): @param isDown: boolean notify if key is pressed or not (True if key is pressed) @param key: ASCII code of key """ + if not self._rfbLayer._ready: + print "Try to send key event on non ready layer" + return try: event = KeyEvent() event.downFlag.value = isDown @@ -509,6 +527,9 @@ class RFBController(object): @param x: x coordinate of mouse pointer @param y: y pointer of mouse pointer """ + if not self._rfbLayer._ready: + print "Try to send pointer event on non ready layer" + return try: event = PointerEvent() event.mask.value = mask