def _serialize_frame(self, opcode, payload=b'', fin=True): rsv = (False, False, False) for extension in reversed(self.extensions): if not extension.enabled(): continue rsv, payload = extension.frame_outbound( self, opcode, rsv, payload, fin) fin_rsv = 0 for bit in rsv: fin_rsv <<= 1 fin_rsv |= int(bit) fin_rsv |= (int(fin) << 3) fin_rsv_opcode = fin_rsv << 4 | opcode payload_length = len(payload) quad_payload = False if payload_length <= MAX_PAYLOAD_NORMAL: first_payload = payload_length second_payload = None elif payload_length <= MAX_PAYLOAD_TWO_BYTE: first_payload = PAYLOAD_LENGTH_TWO_BYTE second_payload = payload_length else: first_payload = PAYLOAD_LENGTH_EIGHT_BYTE second_payload = payload_length quad_payload = True if self.client: first_payload |= 1 << 7 header = bytes([fin_rsv_opcode, first_payload]) if second_payload is not None: if opcode.iscontrol(): raise ValueError("payload too long for control frame") if quad_payload: header += struct.pack('!Q', second_payload) else: header += struct.pack('!H', second_payload) if self.client: # "The masking key is a 32-bit value chosen at random by the # client. When preparing a masked frame, the client MUST pick a # fresh masking key from the set of allowed 32-bit values. The # masking key needs to be unpredictable; thus, the masking key # MUST be derived from a strong source of entropy, and the masking # key for a given frame MUST NOT make it simple for a server/proxy # to predict the masking key for a subsequent frame. The # unpredictability of the masking key is essential to prevent # authors of malicious applications from selecting the bytes that # appear on the wire." # -- https://tools.ietf.org/html/rfc6455#section-5.3 masking_key = os.urandom(4) masker = XorMaskerSimple(masking_key) return header + masking_key + masker.process(payload) else: return header + payload
def _serialize_frame(self, opcode, payload=b'', fin=True): rsv = RsvBits(False, False, False) for extension in reversed(self.extensions): rsv, payload = extension.frame_outbound(self, opcode, rsv, payload, fin) fin_rsv_opcode = self._make_fin_rsv_opcode(fin, rsv, opcode) payload_length = len(payload) quad_payload = False if payload_length <= MAX_PAYLOAD_NORMAL: first_payload = payload_length second_payload = None elif payload_length <= MAX_PAYLOAD_TWO_BYTE: first_payload = PAYLOAD_LENGTH_TWO_BYTE second_payload = payload_length else: first_payload = PAYLOAD_LENGTH_EIGHT_BYTE second_payload = payload_length quad_payload = True if self.client: first_payload |= 1 << 7 header = bytearray([fin_rsv_opcode, first_payload]) if second_payload is not None: if opcode.iscontrol(): raise ValueError("payload too long for control frame") if quad_payload: header += bytearray(struct.pack('!Q', second_payload)) else: header += bytearray(struct.pack('!H', second_payload)) if self.client: # "The masking key is a 32-bit value chosen at random by the # client. When preparing a masked frame, the client MUST pick a # fresh masking key from the set of allowed 32-bit values. The # masking key needs to be unpredictable; thus, the masking key # MUST be derived from a strong source of entropy, and the masking # key for a given frame MUST NOT make it simple for a server/proxy # to predict the masking key for a subsequent frame. The # unpredictability of the masking key is essential to prevent # authors of malicious applications from selecting the bytes that # appear on the wire." # -- https://tools.ietf.org/html/rfc6455#section-5.3 masking_key = os.urandom(4) masker = XorMaskerSimple(masking_key) return header + masking_key + masker.process(payload) return header + payload
def _apply_mask(self, mask, data): masker = XorMaskerSimple(mask) return masker.process(data)
def mask(self, data): if self.masking_key: masker = XorMaskerSimple(self.masking_key) return masker.process(data) return data
def test_xormasker(): masker = XorMaskerSimple(b'\xf0\xf0\x0f\x0f') assert b'\xf0\xf0\x0f\x0f\xf0\xf0' == masker.process(b'\x00'*6) assert masker.pointer() == 6 assert b'\x0f\x0f\xf0\xf0\x0f\x0f' == masker.process(b'\x00'*6) assert masker.pointer() == 12
def _apply_mask(self, mask, data): masker = XorMaskerSimple(mask) return masker.process(data)
def mask(self, data): if self.masking_key: masker = XorMaskerSimple(self.masking_key) return masker.process(data) return data