def __init__(self, listener): """ @param listener: listener use to inform new orders """ RawLayer.__init__(self) #set client listener self._clientListener = listener #useful for RFB protocol self._callbackBody = None #protocol version negotiated self._version = String(ProtocolVersion.RFB003008) #number security launch by server self._securityLevel = UInt8(SecurityType.INVALID) #shared FrameBuffer client init message self._sharedFlag = UInt8(False) #server init message #which contain FrameBuffer dim and pixel format self._serverInit = ServerInit() #client pixel format self._pixelFormat = PixelFormat() #server name self._serverName = String() #nb rectangle self._nbRect = 0 #current rectangle header self._currentRect = Rectangle() #for vnc security type self._password = '******' * 8
def readExtendedFastPathHeader(self, data): """ @summary: Fast path header may be on 1 byte more @param data: {Stream} from twisted layer """ if self._isClient: leftPart = UInt8() data.readType(leftPart) self._lastShortLength.value &= ~0x80 packetSize = (self._lastShortLength.value << 8) + leftPart.value #next state is fast patn data self.expect(packetSize - 3, self.readFastPath) return if self._lastShortLength.value & 0xFF == 0x82: size = UInt16Be() data.readType(size) packetSize = size.value else: #0x81 or other leftPart = UInt8() data.readType(leftPart) self._lastShortLength.value &= ~0x80 packetSize = leftPart.value #next state is fast path data self.expect(packetSize, self.readFastPath)
def __init__(self): CompositeType.__init__(self) self.len = UInt8(lambda:sizeof(self) - 1) self.code = UInt8(MessageType.X224_TPDU_CONNECTION_CONFIRM, constant = True) self.padding = (UInt16Be(), UInt16Be(), UInt8()) #read if there is enough data self.protocolNeg = Negotiation(optional = True)
def __init__(self, conditional): CompositeType.__init__(self, conditional=conditional) self.ProductMajorVersion = UInt8(MajorVersion.WINDOWS_MAJOR_VERSION_6) self.ProductMinorVersion = UInt8(MinorVersion.WINDOWS_MINOR_VERSION_0) self.ProductBuild = UInt16Le(6002) self.Reserved = UInt24Le() self.NTLMRevisionCurrent = UInt8(NTLMRevision.NTLMSSP_REVISION_W2K3)
def send(self, message): """ @summary: Send encompassed data @param message: {network.Type} message to send """ RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
def readInteger(s): """ @summary: Read integer structure from stream @param s: stream @return: int or long python """ if not readUniversalTag(s, Tag.BER_TAG_INTEGER, False): raise InvalidExpectedDataException("Bad integer tag") size = readLength(s) if size == 1: integer = UInt8() s.readType(integer) return integer.value elif size == 2: integer = UInt16Be() s.readType(integer) return integer.value elif size == 3: integer1 = UInt8() integer2 = UInt16Be() s.readType(integer1) s.readType(integer2) return integer2.value + (integer1.value << 16) elif size == 4: integer = UInt32Be() s.readType(integer) return integer.value else: raise InvalidExpectedDataException("Wrong integer size")
def __init__(self, message=None): CompositeType.__init__(self) #preambule self.bMsgtype = UInt8( lambda: self.licensingMessage.__class__._MESSAGE_TYPE_) self.flag = UInt8(Preambule.PREAMBLE_VERSION_3_0) self.wMsgSize = UInt16Le(lambda: sizeof(self)) def LicensingMessageFactory(): """ @summary: factory for message nego Use in read mode """ for c in [ LicensingErrorMessage, ServerLicenseRequest, ClientNewLicenseRequest, ServerPlatformChallenge, ClientPLatformChallengeResponse ]: if self.bMsgtype.value == c._MESSAGE_TYPE_: return c(readLen=self.wMsgSize - 4) log.debug("unknown license message : %s" % self.bMsgtype.value) return String() if message is None: message = FactoryType(LicensingMessageFactory) elif not "_MESSAGE_TYPE_" in message.__class__.__dict__: raise InvalidExpectedDataException( "Try to send an invalid license message") self.licensingMessage = message
def __init__(self, readLen=None): CompositeType.__init__(self, readLen=readLen) self.rdpVersion = UInt32Le(Version.RDP_VERSION_5_PLUS) self.desktopWidth = UInt16Le(1280) self.desktopHeight = UInt16Le(800) self.colorDepth = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP) self.sasSequence = UInt16Le(Sequence.RNS_UD_SAS_DEL) self.kbdLayout = UInt32Le(KeyboardLayout.US) self.clientBuild = UInt32Le(3790) self.clientName = String("rdpy" + "\x00" * 11, readLen=UInt8(32), unicode=True) 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 = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP) self.clientProductId = UInt16Le(1) self.serialNumber = UInt32Le(0) self.highColorDepth = UInt16Le(HighColor.HIGH_COLOR_24BPP) self.supportedColorDepths = UInt16Le(Support.RNS_UD_15BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT | Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_32BPP_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()
def __init__(self, updateData=None): CompositeType.__init__(self) self.updateHeader = UInt8( lambda: updateData.__class__._FASTPATH_UPDATE_TYPE_) self.compressionFlags = UInt8(conditional=lambda: ( (self.updateHeader.value >> 4 ) & FastPathOutputCompression.FASTPATH_OUTPUT_COMPRESSION_USED)) self.size = UInt16Le(lambda: sizeof(self.updateData)) def UpdateDataFactory(): """ @summary: Create correct object in accordance to self.updateHeader field """ for c in [FastPathBitmapUpdateDataPDU]: if (self.updateHeader.value & 0xf) == c._FASTPATH_UPDATE_TYPE_: return c() log.debug("unknown Fast Path PDU update data type : %s" % hex(self.updateHeader.value & 0xf)) return String() if updateData is None: updateData = FactoryType(UpdateDataFactory) elif not "_FASTPATH_UPDATE_TYPE_" in updateData.__class__.__dict__: raise InvalidExpectedDataException( "Try to send an invalid fast path data update PDU") self.updateData = updateData
def readHeader(self, data): """ @summary: Read header of TPKT packet @param data: {Stream} received from twisted layer """ #first read packet version version = UInt8() data.readType(version) #classic packet if version.value == Action.FASTPATH_ACTION_X224: #padding data.readType(UInt8()) #read end header self.expect(2, self.readExtendedHeader) else: #is fast path packet self._secFlag = ((version.value >> 6) & 0x3) data.readType(self._lastShortLength) if self._lastShortLength.value & 0x80: #size is 2 byte more if self._lastShortLength.value & 0xFF == 0x82: self.expect(2, self.readExtendedFastPathHeader) else: self.expect(1, self.readExtendedFastPathHeader) return if self._isClient: self.expect(self._lastShortLength.value - 2, self.readFastPath) else: self.expect(self._lastShortLength.value, self.readFastPath)
def sendPixelFormat(self, pixelFormat): """ @summary: Send pixel format structure Very important packet that inform the image struct supported by the client @param pixelFormat: PixelFormat struct """ self.send((UInt8(ClientToServerMessages.PIXEL_FORMAT), UInt16Be(), UInt8(), pixelFormat))
def sendSetEncoding(self): """ @summary: Send set encoding packet Actually only RAW bitmap encoding are used """ self.send( (UInt8(ClientToServerMessages.ENCODING), UInt8(), UInt16Be(1), SInt32Be(Encoding.RAW)))
def __init__(self, optional = False): CompositeType.__init__(self, optional = optional) self.code = UInt8() self.flag = UInt8(0) #always 8 self.len = UInt16Le(0x0008, constant = True) self.selectedProtocol = UInt32Le(conditional = lambda: (self.code.value != NegociationType.TYPE_RDP_NEG_FAILURE)) self.failureCode = UInt32Le(conditional = lambda: (self.code.value == NegociationType.TYPE_RDP_NEG_FAILURE))
def __init__(self): CompositeType.__init__(self) self.len = UInt8(lambda:sizeof(self) - 1) self.code = UInt8(MessageType.X224_TPDU_CONNECTION_REQUEST, constant = True) self.padding = (UInt16Be(), UInt16Be(), UInt8()) self.cookie = String(until = "\x0d\x0a", conditional = lambda:(self.len._is_readed and self.len.value > 14)) #read if there is enough data self.protocolNeg = Negotiation(optional = True)
def __init__(self, size, pduType2=0, shareId=0): CompositeType.__init__(self) self.shareId = UInt32Le(shareId) self.pad1 = UInt8() self.streamId = UInt8(StreamId.STREAM_LOW) self.uncompressedLength = UInt16Le(lambda: (UInt16Le(size).value - 8)) self.pduType2 = UInt8(pduType2) self.compressedType = UInt8() self.compressedLength = UInt16Le()
def writeLength(size): """ @summary: Return structure length as expected in BER specification @param size: int or python long @return: UInt8 or (UInt8(0x82), UInt16Be) """ if size > 0x7f: return (UInt8(0x82), UInt16Be(size)) else: return UInt8(size)
def writeBoolean(b): """ @summary: Return structure that represent boolean in BER specification @param b: boolean @return: BER boolean block """ boolean = UInt8(0) if b: boolean = UInt8(0xff) return (writeUniversalTag(Tag.BER_TAG_BOOLEAN, False), writeLength(1), boolean)
def send(self, channelId, data): """ @summary: Specific send function for channelId @param channelId: {integer} Channel use to send @param data: {type.type | tuple} message to send """ self._transport.send((self.writeMCSPDUHeader(UInt8(self._sendOpcode)), per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE), per.writeInteger16(channelId), UInt8(0x70), per.writeLength(sizeof(data)), data))
def writeApplicationTag(tag, size): """ @summary: Return structure that represent BER application tag @param tag: int python that match an uint8(0xff) @param size: size to rest of packet """ if tag > 30: return (UInt8((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | Tag.BER_TAG_MASK), UInt8(tag), writeLength(size)) else: return (UInt8((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | (Tag.BER_TAG_MASK & tag)), writeLength(size))
def __init__(self, readLen=None): CompositeType.__init__(self, readLen=readLen) self.destLeft = UInt16Le() self.destTop = UInt16Le() self.destRight = UInt16Le() self.destBottom = UInt16Le() self.width = UInt16Le() self.height = UInt16Le() self.bpp = UInt8() self.format = UInt8() self.length = UInt32Le(lambda: sizeof(self.data)) self.data = String(readLen=self.length)
def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.osMajorType = UInt16Le() self.osMinorType = UInt16Le() self.protocolVersion = UInt16Le(0x0200, constant = True) self.pad2octetsA = UInt16Le() self.generalCompressionTypes = UInt16Le(0, constant = True) self.extraFlags = UInt16Le() self.updateCapabilityFlag = UInt16Le(0, constant = True) self.remoteUnshareFlag = UInt16Le(0, constant = True) self.generalCompressionLevel = UInt16Le(0, constant = True) self.refreshRectSupport = UInt8() self.suppressOutputSupport = UInt8()
def __init__(self, readLen=None): CompositeType.__init__(self, readLen=readLen) self.cacheFlags = UInt16Le() self.pad2 = UInt8() self.numCellCaches = UInt8() self.bitmapCache0CellInfo = UInt32Le() self.bitmapCache1CellInfo = UInt32Le() self.bitmapCache2CellInfo = UInt32Le() self.bitmapCache3CellInfo = UInt32Le() self.bitmapCache4CellInfo = UInt32Le() self.pad3_1 = UInt32Le() self.pad3_2 = UInt32Le() self.pad3_3 = UInt32Le()
def __init__(self, readLen = None): CompositeType.__init__(self, readLen = readLen) self.preferredBitsPerPixel = UInt16Le() self.receive1BitPerPixel = UInt16Le(0x0001) self.receive4BitsPerPixel = UInt16Le(0x0001) self.receive8BitsPerPixel = UInt16Le(0x0001) self.desktopWidth = UInt16Le() self.desktopHeight = UInt16Le() self.pad2octets = UInt16Le() self.desktopResizeFlag = UInt16Le() self.bitmapCompressionFlag = UInt16Le(0x0001, constant = True) self.highColorFlags = UInt8(0) self.drawingFlags = UInt8() self.multipleRectangleSupport = UInt16Le(0x0001, constant = True) self.pad2octetsB = UInt16Le()
def __init__(self, name="", options=0): CompositeType.__init__(self) #name of channel self.name = String(name[0:8] + "\x00" * (8 - len(name)), readLen=UInt8(8)) #unknown self.options = UInt32Le()
def recvChannelJoinRequest(self, data): """ @summary: Receive for each client channel a request Send Channel Join Confirm or Connect upper layer when all channel are joined @param data: {Stream} """ opcode = UInt8() data.readType(opcode) if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.CHANNEL_JOIN_REQUEST): raise InvalidExpectedDataException( "Invalid MCS PDU : CHANNEL_JOIN_REQUEST expected") userId = per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE) if self._userId != userId: raise InvalidExpectedDataException("Invalid MCS User Id") channelId = per.readInteger16(data) #actually algo support virtual channel but RDPY have no virtual channel confirm = 0 if channelId in self._channels.keys( ) or channelId == self._userId else 1 self.sendChannelJoinConfirm(channelId, confirm) self._nbChannelConfirmed += 1 if self._nbChannelConfirmed == self._serverSettings.getBlock( gcc.MessageType.SC_NET).channelCount.value + 2: self.allChannelConnected()
def sendErectDomainRequest(self): """ @summary: Send a formated erect domain request for RDP connection """ self._transport.send( (self.writeMCSPDUHeader(UInt8(DomainMCSPDU.ERECT_DOMAIN_REQUEST)), per.writeInteger(0), per.writeInteger(0)))
def recvChannelJoinConfirm(self, data): """ @summary: Receive a channel join confirm from server client automata function @param data: {Stream} """ opcode = UInt8() data.readType(opcode) if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.CHANNEL_JOIN_CONFIRM): raise InvalidExpectedDataException( "Invalid MCS PDU : CHANNEL_JOIN_CONFIRM expected") confirm = per.readEnumerates(data) userId = per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE) if self._userId != userId: raise InvalidExpectedDataException("Invalid MCS User Id") channelId = per.readInteger16(data) #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[i].value: self._channels[channelId] = self._virtualChannels[i][1] self.connectNextChannel()
def recvConnectResponse(self, data): """ @summary: Receive MCS connect response from server Send Erect domain Request Send Attach User Request Wait Attach User Confirm @param data: {Stream} """ ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE)) ber.readEnumerated(data) ber.readInteger(data) self.readDomainParams(data) if not ber.readUniversalTag(data, ber.Tag.BER_TAG_OCTET_STRING, False): raise InvalidExpectedDataException("invalid expected BER tag") gccRequestLength = ber.readLength(data) if data.dataLen() != gccRequestLength: raise InvalidSize("bad size of GCC request") self._serverSettings = gcc.readConferenceCreateResponse(data) #send domain request self.sendErectDomainRequest() #send attach user request self.sendAttachUserRequest() #now wait user confirm from server self.setNextState(self.recvAttachUserConfirm)
def recvData(self, data): """ @summary: Main receive method @param data: {Stream} """ opcode = UInt8() data.readType(opcode) if self.readMCSPDUHeader(opcode.value, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM): log.info("MCS DISCONNECT_PROVIDER_ULTIMATUM") self._transport.close() return #client case elif not self.readMCSPDUHeader(opcode.value, self._receiveOpcode): raise InvalidExpectedDataException( "Invalid expected MCS opcode receive data") #server user id per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE) channelId = per.readInteger16(data) per.readEnumerates(data) per.readLength(data) #channel id doesn't match a requested layer if not self._channels.has_key(channelId): log.error("receive data for an unconnected layer") return self._channels[channelId].recv(data)
def recvConnectInitial(self, data): """ @summary: Receive MCS connect initial from client Send Connect Response Wait Erect Domain Request @param data: {Stream} """ ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_INITIAL)) ber.readOctetString(data) ber.readOctetString(data) if not ber.readBoolean(data): raise InvalidExpectedDataException( "invalid expected BER boolean tag") self.readDomainParams(data) self.readDomainParams(data) self.readDomainParams(data) self._clientSettings = gcc.readConferenceCreateRequest( Stream(ber.readOctetString(data))) if not self._clientSettings.CS_NET is None: i = 1 for channelDef in self._clientSettings.CS_NET.channelDefArray._array: self._serverSettings.SC_NET.channelIdArray._array.append( UInt16Le(i + Channel.MCS_GLOBAL_CHANNEL)) #if channel can be handle by serve add it for serverChannelDef, layer in self._virtualChannels: if channelDef.name == serverChannelDef.name: self._channels[i + Channel.MCS_GLOBAL_CHANNEL] = layer i += 1 self.sendConnectResponse() self.setNextState(self.recvErectDomainRequest)