def writeClientCoreData(self, stream: BytesIO, core: ClientCoreData): stream.write(Uint32LE.pack(core.version)) stream.write(Uint16LE.pack(core.desktopWidth)) stream.write(Uint16LE.pack(core.desktopHeight)) stream.write(Uint16LE.pack(core.colorDepth)) stream.write(Uint16LE.pack(core.sasSequence)) stream.write(Uint32LE.pack(core.keyboardLayout)) stream.write(Uint32LE.pack(core.clientBuild)) stream.write(encodeUTF16LE(core.clientName).ljust(32, b"\x00")[: 32]) stream.write(Uint32LE.pack(core.keyboardType)) stream.write(Uint32LE.pack(core.keyboardSubType)) stream.write(Uint32LE.pack(core.keyboardFunctionKey)) stream.write(core.imeFileName) try: stream.write(Uint16LE.pack(core.postBeta2ColorDepth)) stream.write(Uint16LE.pack(core.clientProductId)) stream.write(Uint32LE.pack(core.serialNumber)) stream.write(Uint16LE.pack(core.highColorDepth)) stream.write(Uint16LE.pack(core.supportedColorDepths)) stream.write(Uint16LE.pack(core.earlyCapabilityFlags)) stream.write(encodeUTF16LE(core.clientDigProductId).ljust(64, b"\x00")[: 64]) stream.write(Uint8.pack(core.connectionType)) stream.write(b"\x00") stream.write(Uint32LE.pack(core.serverSelectedProtocol)) stream.write(Uint32LE.pack(core.desktopPhysicalWidth)) stream.write(Uint32LE.pack(core.desktopPhysicalHeight)) stream.write(Uint16LE.pack(core.desktopOrientation)) stream.write(Uint32LE.pack(core.desktopScaleFactor)) stream.write(Uint32LE.pack(core.deviceScaleFactor)) except struct.error: # We tried to write an optional field which was not present. Stop writing beyond this point. pass
def write(self, pdu): """ Encode a Client Info PDU to bytes. :param pdu: the Client Info PDU. :type pdu: ClientInfoPDU :return: str """ stream = BytesIO() stream.write(Uint32LE.pack(pdu.codePage)) stream.write(Uint32LE.pack(pdu.flags)) isUnicode = pdu.flags & ClientInfoFlags.INFO_UNICODE != 0 hasNullBytes = pdu.codePage == 1252 or isUnicode nullByteCount = 1 if hasNullBytes else 0 unicodeMultiplier = 2 if isUnicode else 0 domain = pdu.domain + "\x00" * nullByteCount username = pdu.username + "\x00" * nullByteCount password = pdu.password + "\x00" * nullByteCount alternateShell = pdu.alternateShell + "\x00" * nullByteCount workingDir = pdu.workingDir + "\x00" * nullByteCount if isUnicode: domain = encodeUTF16LE(domain) username = encodeUTF16LE(username) password = encodeUTF16LE(password) alternateShell = encodeUTF16LE(alternateShell) workingDir = encodeUTF16LE(workingDir) else: domain = domain.encode() username = username.encode() password = password.encode() alternateShell = alternateShell.encode() workingDir = workingDir.encode() domainLength = len(domain) - nullByteCount * unicodeMultiplier usernameLength = len(username) - nullByteCount * unicodeMultiplier passwordLength = len(password) - nullByteCount * unicodeMultiplier alternateShellLength = len( alternateShell) - nullByteCount * unicodeMultiplier workingDirLength = len(workingDir) - nullByteCount * unicodeMultiplier stream.write(Uint16LE.pack(domainLength)) stream.write(Uint16LE.pack(usernameLength)) stream.write(Uint16LE.pack(passwordLength)) stream.write(Uint16LE.pack(alternateShellLength)) stream.write(Uint16LE.pack(workingDirLength)) stream.write(domain) stream.write(username) stream.write(password) stream.write(alternateShell) stream.write(workingDir) if pdu.extraInfo is not None: extraInfoBytes = self.writeExtraInfo(pdu.extraInfo) stream.write(extraInfoBytes) return stream.getvalue()