Example #1
0
    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
Example #2
0
    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
Example #3
0
    def parse_more_gen(self):
        # Consume as much as we can from self._buffer, yielding events, and
        # then yield None when we need more data. Or raise ParseFailed.

        # XX FIXME this should probably be refactored so that we never see
        # disabled extensions in the first place...
        self.extensions = [ext for ext in self.extensions if ext.enabled()]

        unfinished_message_opcode = None
        unfinished_message_decoder = None
        effective_opcode = None
        while effective_opcode is not Opcode.CLOSE:
            header = yield from self._parse_header()

            if unfinished_message_opcode is None:
                if header.opcode is Opcode.CONTINUATION:
                    raise ParseFailed("unexpected CONTINUATION")
                elif not header.opcode.iscontrol():
                    # Neither CONTINUATION nor control -> starting a new
                    # unfinished message
                    unfinished_message_opcode = header.opcode
            elif not header.opcode.iscontrol():
                # We're in the middle of an unfinished message
                if header.opcode is not Opcode.CONTINUATION:
                    raise ParseFailed("expected CONTINUATION, not {!r}"
                                      .format(header.opcode))

            effective_opcode = header.opcode
            if effective_opcode is Opcode.CONTINUATION:
                effective_opcode = unfinished_message_opcode

            if header.masking_key == NULL_MASK:
                masker = XorMaskerNull()
            else:
                masker = XorMaskerSimple(header.masking_key)

            if unfinished_message_opcode is Opcode.TEXT and \
               unfinished_message_decoder is None:
                unfinished_message_decoder = getincrementaldecoder("utf-8")()

            message_finished = yield from self._parse_frame_payload(
                opcode=effective_opcode,
                remaining=header.payload_len,
                message_decoder=unfinished_message_decoder,
                masker=masker,
                fin_flag=header.fin
            )

            if message_finished and not effective_opcode.iscontrol():
                # This isn't a control, so if this message is finished
                # then the unfinished message is also finished.
                unfinished_message_opcode = None
                unfinished_message_decoder = None
Example #4
0
    def parse_header(self) -> bool:
        data = self.buffer.consume_exactly(2)
        if data is None:
            self.buffer.rollback()
            return False

        fin = bool(data[0] & FIN_MASK)
        rsv = RsvBits(
            bool(data[0] & RSV1_MASK),
            bool(data[0] & RSV2_MASK),
            bool(data[0] & RSV3_MASK),
        )
        opcode = data[0] & OPCODE_MASK
        try:
            opcode = Opcode(opcode)
        except ValueError:
            raise ParseFailed("Invalid opcode {:#x}".format(opcode))

        if opcode.iscontrol() and not fin:
            raise ParseFailed("Invalid attempt to fragment control frame")

        has_mask = bool(data[1] & MASK_MASK)
        payload_len = data[1] & PAYLOAD_LEN_MASK
        payload_len = self.parse_extended_payload_length(opcode, payload_len)
        if payload_len is None:
            self.buffer.rollback()
            return False

        self.extension_processing(opcode, rsv, payload_len)

        if has_mask and self.client:
            raise ParseFailed("client received unexpected masked frame")
        if not has_mask and not self.client:
            raise ParseFailed("server received unexpected unmasked frame")
        if has_mask:
            masking_key = self.buffer.consume_exactly(4)
            if masking_key is None:
                self.buffer.rollback()
                return False
            self.masker = XorMaskerSimple(masking_key)
        else:
            self.masker = XorMaskerNull()

        self.buffer.commit()
        self.header = Header(fin, rsv, opcode, payload_len, None)
        self.effective_opcode = self.header.opcode
        if self.header.opcode.iscontrol():
            self.payload_required = payload_len
        else:
            self.payload_required = 0
        self.payload_consumed = 0
        return True
Example #5
0
 def _mask(_m, _d):
     return XorMaskerSimple(_m).process(_d)
Example #6
0
def mask2(mask, data):
    return XorMaskerSimple(mask).process(data)
Example #7
0
 def _apply_mask(self, mask, data):
     masker = XorMaskerSimple(mask)
     return masker.process(data)
Example #8
0
 def mask(self, data):
     if self.masking_key:
         masker = XorMaskerSimple(self.masking_key)
         return masker.process(data)
     return data
Example #9
0
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
Example #10
0
 def mask(masking_key, data):
     return XorMaskerSimple(masking_key).process(data)
Example #11
0
 def _apply_mask(self, mask, data):
     masker = XorMaskerSimple(mask)
     return masker.process(data)
Example #12
0
 def mask(self, data):
     if self.masking_key:
         masker = XorMaskerSimple(self.masking_key)
         return masker.process(data)
     return data