def parseExtraInfo(self, data: bytes) -> ClientExtraInfo: stream = BytesIO(data) clientAddressFamily = Uint16LE.unpack(stream) clientAddressLength = Uint16LE.unpack(stream) clientAddress = stream.read(clientAddressLength) clientDirLength = Uint16LE.unpack(stream) clientDir = stream.read(clientDirLength) extraInfo = ClientExtraInfo(clientAddressFamily, clientAddress, clientDir) stream = StrictStream(stream) try: extraInfo.clientTimeZone = stream.read(172) extraInfo.clientSessionID = Uint32LE.unpack(stream) extraInfo.performanceFlags = Uint32LE.unpack(stream) autoReconnectCookieLength = Uint16LE.unpack(stream) extraInfo.autoReconnectCookie = stream.read( autoReconnectCookieLength) stream.read(4) dynamicDSTTimeZoneKeyNameLength = Uint16LE.unpack(stream) extraInfo.dynamicDSTTimeZoneKeyName = stream.read( dynamicDSTTimeZoneKeyNameLength) extraInfo.dynamicDaylightTimeDisabled = bool( Uint16LE.unpack(stream)) except EOFError: pass return extraInfo
def parseServerSecurityData(self, stream): stream = StrictStream(stream) encryptionMethod = EncryptionMethod(Uint32LE.unpack(stream)) encryptionLevel = EncryptionLevel(Uint32LE.unpack(stream)) serverRandom = None serverCertificate = None try: serverRandomLength = Uint32LE.unpack(stream) serverCertificateLength = Uint32LE.unpack(stream) serverRandom = stream.read(serverRandomLength) serverCertificate = stream.read(serverCertificateLength) serverCertificate = self.parseServerCertificate(serverCertificate) except EOFError: pass return ServerSecurityData(encryptionMethod, encryptionLevel, serverRandom, serverCertificate)
def parseServerCoreData(self, stream: BytesIO) -> ServerCoreData: stream = StrictStream(stream) clientRequestedProtocols = None earlyCapabilityFlags = None version = Uint32LE.unpack(stream) try: clientRequestedProtocols = Uint32LE.unpack(stream) earlyCapabilityFlags = Uint32LE.unpack(stream) except EOFError: pass return ServerCoreData(version, clientRequestedProtocols, earlyCapabilityFlags)
def parseClientCoreData(self, stream: BytesIO) -> ClientCoreData: stream = StrictStream(stream) # 128 bytes minimum (excluding header) version = RDPVersion(Uint32LE.unpack(stream)) desktopWidth = Uint16LE.unpack(stream) desktopHeight = Uint16LE.unpack(stream) colorDepth = ColorDepth(Uint16LE.unpack(stream)) sasSequence = Uint16LE.unpack(stream) keyboardLayout = Uint32LE.unpack(stream) clientBuild = Uint32LE.unpack(stream) clientName = decodeUTF16LE(stream.read(32)) keyboardType = Uint32LE.unpack(stream) keyboardSubType = Uint32LE.unpack(stream) keyboardFunctionKey = Uint32LE.unpack(stream) imeFileName = stream.read(64) core = ClientCoreData(version, desktopWidth, desktopHeight, colorDepth, sasSequence, keyboardLayout, clientBuild, clientName, keyboardType, keyboardSubType, keyboardFunctionKey, imeFileName) # Optional data # The optional fields are read in order. If one of them is not present, then all subsequent fields are also not present. try: core.postBeta2ColorDepth = Uint16LE.unpack(stream) core.clientProductId = Uint16LE.unpack(stream) core.serialNumber = Uint32LE.unpack(stream) # Should match HighColorDepth enum most of the time, but in order to support scanners and we script, we have to loosely accept this one # Anyway, the server will reject it and enforce another one core.highColorDepth = Uint16LE.unpack(stream) core.supportedColorDepths = Uint16LE.unpack(stream) core.earlyCapabilityFlags = Uint16LE.unpack(stream) core.clientDigProductId = decodeUTF16LE(stream.read(64)) core.connectionType = ConnectionType(Uint8.unpack(stream)) stream.read(1) core.serverSelectedProtocol = Uint32LE.unpack(stream) core.desktopPhysicalWidth = Uint32LE.unpack(stream) core.desktopPhysicalHeight = Uint32LE.unpack(stream) core.desktopOrientation = DesktopOrientation( Uint16LE.unpack(stream)) core.desktopScaleFactor = Uint32LE.unpack(stream) core.deviceScaleFactor = Uint32LE.unpack(stream) except EOFError: # The stream has reached the end, we don't have any more optional fields. This exception can be ignored. pass return core