From 1407830280383e50a8af848a0c564c4912df5a52 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 20 Oct 2016 09:45:18 +1300 Subject: netlib.human -> mitmproxy.utils.human --- netlib/websockets/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'netlib/websockets/frame.py') diff --git a/netlib/websockets/frame.py b/netlib/websockets/frame.py index b58fa289..02d74112 100644 --- a/netlib/websockets/frame.py +++ b/netlib/websockets/frame.py @@ -5,7 +5,7 @@ import io from netlib import tcp from netlib import strutils from netlib import utils -from netlib import human +from mitmproxy.utils import human from .masker import Masker -- cgit v1.2.3 From f45f4e677e8cddba8160d1e4e02ca8a4515e3456 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 20 Oct 2016 10:11:58 +1300 Subject: netlib.strutils -> mitmproxy.utils.strutils --- netlib/websockets/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'netlib/websockets/frame.py') diff --git a/netlib/websockets/frame.py b/netlib/websockets/frame.py index 02d74112..e022a95c 100644 --- a/netlib/websockets/frame.py +++ b/netlib/websockets/frame.py @@ -3,7 +3,7 @@ import struct import io from netlib import tcp -from netlib import strutils +from mitmproxy.utils import strutils from netlib import utils from mitmproxy.utils import human from .masker import Masker -- cgit v1.2.3 From 95551265852e6ff05ab5e5204e1a919f66fa4eae Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 20 Oct 2016 10:32:09 +1300 Subject: netlib.utils.BiDi -> mitmproxy.types.bidi.BiDi --- netlib/websockets/frame.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'netlib/websockets/frame.py') diff --git a/netlib/websockets/frame.py b/netlib/websockets/frame.py index e022a95c..26303094 100644 --- a/netlib/websockets/frame.py +++ b/netlib/websockets/frame.py @@ -6,6 +6,7 @@ from netlib import tcp from mitmproxy.utils import strutils from netlib import utils from mitmproxy.utils import human +from mitmproxy.types import bidi from .masker import Masker @@ -15,7 +16,7 @@ MAX_64_BIT_INT = (1 << 64) DEFAULT = object() # RFC 6455, Section 5.2 - Base Framing Protocol -OPCODE = utils.BiDi( +OPCODE = bidi.BiDi( CONTINUE=0x00, TEXT=0x01, BINARY=0x02, @@ -25,7 +26,7 @@ OPCODE = utils.BiDi( ) # RFC 6455, Section 7.4.1 - Defined Status Codes -CLOSE_REASON = utils.BiDi( +CLOSE_REASON = bidi.BiDi( NORMAL_CLOSURE=1000, GOING_AWAY=1001, PROTOCOL_ERROR=1002, -- cgit v1.2.3 From e0f3cce14cb26d10bc259d431f688fb0d10ab3f5 Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 20 Oct 2016 10:38:57 +1300 Subject: netlib.utils.[get,set]bit -> mitmproxy.utils.bits --- netlib/websockets/frame.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'netlib/websockets/frame.py') diff --git a/netlib/websockets/frame.py b/netlib/websockets/frame.py index 26303094..bc4ae43a 100644 --- a/netlib/websockets/frame.py +++ b/netlib/websockets/frame.py @@ -4,7 +4,7 @@ import io from netlib import tcp from mitmproxy.utils import strutils -from netlib import utils +from mitmproxy.utils import bits from mitmproxy.utils import human from mitmproxy.types import bidi from .masker import Masker @@ -119,13 +119,13 @@ class FrameHeader: return "".join(vals) def __bytes__(self): - first_byte = utils.setbit(0, 7, self.fin) - first_byte = utils.setbit(first_byte, 6, self.rsv1) - first_byte = utils.setbit(first_byte, 5, self.rsv2) - first_byte = utils.setbit(first_byte, 4, self.rsv3) + first_byte = bits.setbit(0, 7, self.fin) + first_byte = bits.setbit(first_byte, 6, self.rsv1) + first_byte = bits.setbit(first_byte, 5, self.rsv2) + first_byte = bits.setbit(first_byte, 4, self.rsv3) first_byte = first_byte | self.opcode - second_byte = utils.setbit(self.length_code, 7, self.mask) + second_byte = bits.setbit(self.length_code, 7, self.mask) b = bytes([first_byte, second_byte]) @@ -152,12 +152,12 @@ class FrameHeader: read a websockets frame header """ first_byte, second_byte = fp.safe_read(2) - fin = utils.getbit(first_byte, 7) - rsv1 = utils.getbit(first_byte, 6) - rsv2 = utils.getbit(first_byte, 5) - rsv3 = utils.getbit(first_byte, 4) + fin = bits.getbit(first_byte, 7) + rsv1 = bits.getbit(first_byte, 6) + rsv2 = bits.getbit(first_byte, 5) + rsv3 = bits.getbit(first_byte, 4) opcode = first_byte & 0xF - mask_bit = utils.getbit(second_byte, 7) + mask_bit = bits.getbit(second_byte, 7) length_code = second_byte & 0x7F # payload_length > 125 indicates you need to read more bytes -- cgit v1.2.3 From 8430f857b504a3e7406dc36e54dc32783569d0dd Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Thu, 20 Oct 2016 11:56:38 +1300 Subject: The final piece: netlib -> mitproxy.net --- netlib/websockets/frame.py | 274 --------------------------------------------- 1 file changed, 274 deletions(-) delete mode 100644 netlib/websockets/frame.py (limited to 'netlib/websockets/frame.py') diff --git a/netlib/websockets/frame.py b/netlib/websockets/frame.py deleted file mode 100644 index bc4ae43a..00000000 --- a/netlib/websockets/frame.py +++ /dev/null @@ -1,274 +0,0 @@ -import os -import struct -import io - -from netlib import tcp -from mitmproxy.utils import strutils -from mitmproxy.utils import bits -from mitmproxy.utils import human -from mitmproxy.types import bidi -from .masker import Masker - - -MAX_16_BIT_INT = (1 << 16) -MAX_64_BIT_INT = (1 << 64) - -DEFAULT = object() - -# RFC 6455, Section 5.2 - Base Framing Protocol -OPCODE = bidi.BiDi( - CONTINUE=0x00, - TEXT=0x01, - BINARY=0x02, - CLOSE=0x08, - PING=0x09, - PONG=0x0a -) - -# RFC 6455, Section 7.4.1 - Defined Status Codes -CLOSE_REASON = bidi.BiDi( - NORMAL_CLOSURE=1000, - GOING_AWAY=1001, - PROTOCOL_ERROR=1002, - UNSUPPORTED_DATA=1003, - RESERVED=1004, - RESERVED_NO_STATUS=1005, - RESERVED_ABNORMAL_CLOSURE=1006, - INVALID_PAYLOAD_DATA=1007, - POLICY_VIOLATION=1008, - MESSAGE_TOO_BIG=1009, - MANDATORY_EXTENSION=1010, - INTERNAL_ERROR=1011, - RESERVED_TLS_HANDHSAKE_FAILED=1015, -) - - -class FrameHeader: - - def __init__( - self, - opcode=OPCODE.TEXT, - payload_length=0, - fin=False, - rsv1=False, - rsv2=False, - rsv3=False, - masking_key=DEFAULT, - mask=DEFAULT, - length_code=DEFAULT - ): - if not 0 <= opcode < 2 ** 4: - raise ValueError("opcode must be 0-16") - self.opcode = opcode - self.payload_length = payload_length - self.fin = fin - self.rsv1 = rsv1 - self.rsv2 = rsv2 - self.rsv3 = rsv3 - - if length_code is DEFAULT: - self.length_code = self._make_length_code(self.payload_length) - else: - self.length_code = length_code - - if mask is DEFAULT and masking_key is DEFAULT: - self.mask = False - self.masking_key = b"" - elif mask is DEFAULT: - self.mask = 1 - self.masking_key = masking_key - elif masking_key is DEFAULT: - self.mask = mask - self.masking_key = os.urandom(4) - else: - self.mask = mask - self.masking_key = masking_key - - if self.masking_key and len(self.masking_key) != 4: - raise ValueError("Masking key must be 4 bytes.") - - @classmethod - def _make_length_code(self, length): - """ - A websockets frame contains an initial length_code, and an optional - extended length code to represent the actual length if length code is - larger than 125 - """ - if length <= 125: - return length - elif length >= 126 and length <= 65535: - return 126 - else: - return 127 - - def __repr__(self): - vals = [ - "ws frame:", - OPCODE.get_name(self.opcode, hex(self.opcode)).lower() - ] - flags = [] - for i in ["fin", "rsv1", "rsv2", "rsv3", "mask"]: - if getattr(self, i): - flags.append(i) - if flags: - vals.extend([":", "|".join(flags)]) - if self.masking_key: - vals.append(":key=%s" % repr(self.masking_key)) - if self.payload_length: - vals.append(" %s" % human.pretty_size(self.payload_length)) - return "".join(vals) - - def __bytes__(self): - first_byte = bits.setbit(0, 7, self.fin) - first_byte = bits.setbit(first_byte, 6, self.rsv1) - first_byte = bits.setbit(first_byte, 5, self.rsv2) - first_byte = bits.setbit(first_byte, 4, self.rsv3) - first_byte = first_byte | self.opcode - - second_byte = bits.setbit(self.length_code, 7, self.mask) - - b = bytes([first_byte, second_byte]) - - if self.payload_length < 126: - pass - elif self.payload_length < MAX_16_BIT_INT: - # '!H' pack as 16 bit unsigned short - # add 2 byte extended payload length - b += struct.pack('!H', self.payload_length) - elif self.payload_length < MAX_64_BIT_INT: - # '!Q' = pack as 64 bit unsigned long long - # add 8 bytes extended payload length - b += struct.pack('!Q', self.payload_length) - else: - raise ValueError("Payload length exceeds 64bit integer") - - if self.masking_key: - b += self.masking_key - return b - - @classmethod - def from_file(cls, fp): - """ - read a websockets frame header - """ - first_byte, second_byte = fp.safe_read(2) - fin = bits.getbit(first_byte, 7) - rsv1 = bits.getbit(first_byte, 6) - rsv2 = bits.getbit(first_byte, 5) - rsv3 = bits.getbit(first_byte, 4) - opcode = first_byte & 0xF - mask_bit = bits.getbit(second_byte, 7) - length_code = second_byte & 0x7F - - # payload_length > 125 indicates you need to read more bytes - # to get the actual payload length - if length_code <= 125: - payload_length = length_code - elif length_code == 126: - payload_length, = struct.unpack("!H", fp.safe_read(2)) - else: # length_code == 127: - payload_length, = struct.unpack("!Q", fp.safe_read(8)) - - # masking key only present if mask bit set - if mask_bit == 1: - masking_key = fp.safe_read(4) - else: - masking_key = None - - return cls( - fin=fin, - rsv1=rsv1, - rsv2=rsv2, - rsv3=rsv3, - opcode=opcode, - mask=mask_bit, - length_code=length_code, - payload_length=payload_length, - masking_key=masking_key, - ) - - def __eq__(self, other): - if isinstance(other, FrameHeader): - return bytes(self) == bytes(other) - return False - - -class Frame: - """ - Represents a single WebSockets frame. - Constructor takes human readable forms of the frame components. - from_bytes() reads from a file-like object to create a new Frame. - - WebSockets Frame as defined in RFC6455 - - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-------+-+-------------+-------------------------------+ - |F|R|R|R| opcode|M| Payload len | Extended payload length | - |I|S|S|S| (4) |A| (7) | (16/64) | - |N|V|V|V| |S| | (if payload len==126/127) | - | |1|2|3| |K| | | - +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - | Extended payload length continued, if payload len == 127 | - + - - - - - - - - - - - - - - - +-------------------------------+ - | |Masking-key, if MASK set to 1 | - +-------------------------------+-------------------------------+ - | Masking-key (continued) | Payload Data | - +-------------------------------- - - - - - - - - - - - - - - - + - : Payload Data continued ... : - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - | Payload Data continued ... | - +---------------------------------------------------------------+ - """ - - def __init__(self, payload=b"", **kwargs): - self.payload = payload - kwargs["payload_length"] = kwargs.get("payload_length", len(payload)) - self.header = FrameHeader(**kwargs) - - @classmethod - def from_bytes(cls, bytestring): - """ - Construct a websocket frame from an in-memory bytestring - to construct a frame from a stream of bytes, use from_file() directly - """ - return cls.from_file(tcp.Reader(io.BytesIO(bytestring))) - - def __repr__(self): - ret = repr(self.header) - if self.payload: - ret = ret + "\nPayload:\n" + strutils.bytes_to_escaped_str(self.payload) - return ret - - def __bytes__(self): - """ - Serialize the frame to wire format. Returns a string. - """ - b = bytes(self.header) - if self.header.masking_key: - b += Masker(self.header.masking_key)(self.payload) - else: - b += self.payload - return b - - @classmethod - def from_file(cls, fp): - """ - read a websockets frame sent by a server or client - - fp is a "file like" object that could be backed by a network - stream or a disk or an in memory stream reader - """ - header = FrameHeader.from_file(fp) - payload = fp.safe_read(header.payload_length) - - if header.mask == 1 and header.masking_key: - payload = Masker(header.masking_key)(payload) - - frame = cls(payload) - frame.header = header - return frame - - def __eq__(self, other): - if isinstance(other, Frame): - return bytes(self) == bytes(other) - return False -- cgit v1.2.3