mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-25 18:03:50 +00:00
upgrade to construct 2.8 and new API
This commit is contained in:
parent
741c2b7b66
commit
33689c6b2d
@ -3,120 +3,122 @@
|
|||||||
# for complete details.
|
# for complete details.
|
||||||
|
|
||||||
|
|
||||||
from construct import (Array, Bytes, Struct, UBInt16, UBInt32, UBInt8, PascalString, Embed, TunnelAdapter, GreedyRange,
|
from construct import (
|
||||||
Switch, OptionalGreedyRange, Optional)
|
Array,
|
||||||
|
Bytes,
|
||||||
from .utils import UBInt24
|
Struct,
|
||||||
|
VarInt,
|
||||||
ProtocolVersion = Struct(
|
Int8ub,
|
||||||
"version",
|
Int16ub,
|
||||||
UBInt8("major"),
|
Int24ub,
|
||||||
UBInt8("minor"),
|
Int32ub,
|
||||||
|
PascalString,
|
||||||
|
Embedded,
|
||||||
|
Prefixed,
|
||||||
|
Range,
|
||||||
|
GreedyRange,
|
||||||
|
Switch,
|
||||||
|
Optional,
|
||||||
)
|
)
|
||||||
|
|
||||||
TLSPlaintext = Struct(
|
ProtocolVersion = "version" / Struct(
|
||||||
"TLSPlaintext",
|
"major" / Int8ub,
|
||||||
UBInt8("type"),
|
"minor" / Int8ub,
|
||||||
|
)
|
||||||
|
|
||||||
|
TLSPlaintext = "TLSPlaintext" / Struct(
|
||||||
|
"type" / Int8ub,
|
||||||
ProtocolVersion,
|
ProtocolVersion,
|
||||||
UBInt16("length"), # TODO: Reject packets with length > 2 ** 14
|
"length" / Int16ub, # TODO: Reject packets with length > 2 ** 14
|
||||||
Bytes("fragment", lambda ctx: ctx.length),
|
"fragment" / Bytes(lambda ctx: ctx.length),
|
||||||
)
|
)
|
||||||
|
|
||||||
TLSCompressed = Struct(
|
TLSCompressed = "TLSCompressed" / Struct(
|
||||||
"TLSCompressed",
|
"type" / Int8ub,
|
||||||
UBInt8("type"),
|
|
||||||
ProtocolVersion,
|
ProtocolVersion,
|
||||||
UBInt16("length"), # TODO: Reject packets with length > 2 ** 14 + 1024
|
"length" / Int16ub, # TODO: Reject packets with length > 2 ** 14 + 1024
|
||||||
Bytes("fragment", lambda ctx: ctx.length),
|
"fragment" / Bytes(lambda ctx: ctx.length),
|
||||||
)
|
)
|
||||||
|
|
||||||
TLSCiphertext = Struct(
|
TLSCiphertext = "TLSCiphertext" / Struct(
|
||||||
"TLSCiphertext",
|
"type" / Int8ub,
|
||||||
UBInt8("type"),
|
|
||||||
ProtocolVersion,
|
ProtocolVersion,
|
||||||
UBInt16("length"), # TODO: Reject packets with length > 2 ** 14 + 2048
|
"length" / Int16ub, # TODO: Reject packets with length > 2 ** 14 + 2048
|
||||||
Bytes("fragment", lambda ctx: ctx.length),
|
"fragment" / Bytes(lambda ctx: ctx.length),
|
||||||
)
|
)
|
||||||
|
|
||||||
Random = Struct(
|
Random = "random" / Struct(
|
||||||
"random",
|
"gmt_unix_time" / Int32ub,
|
||||||
UBInt32("gmt_unix_time"),
|
"random_bytes" / Bytes(28),
|
||||||
Bytes("random_bytes", 28),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SessionID = Struct(
|
SessionID = "session_id" / Struct(
|
||||||
"session_id",
|
"length" / Int8ub,
|
||||||
UBInt8("length"),
|
"session_id" / Bytes(lambda ctx: ctx.length),
|
||||||
Bytes("session_id", lambda ctx: ctx.length),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
CipherSuites = Struct(
|
CipherSuites = "cipher_suites" / Struct(
|
||||||
"cipher_suites",
|
"length" / Int16ub, # TODO: Reject packets of length 0
|
||||||
UBInt16("length"), # TODO: Reject packets of length 0
|
Array(lambda ctx: ctx.length // 2, "cipher_suites" / Int16ub),
|
||||||
Array(lambda ctx: ctx.length // 2, UBInt16("cipher_suites")),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
CompressionMethods = Struct(
|
CompressionMethods = "compression_methods" / Struct(
|
||||||
"compression_methods",
|
"length" / Int8ub, # TODO: Reject packets of length 0
|
||||||
UBInt8("length"), # TODO: Reject packets of length 0
|
Array(lambda ctx: ctx.length, "compression_methods" / Int8ub),
|
||||||
Array(lambda ctx: ctx.length, UBInt8("compression_methods")),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ServerName = Struct(
|
ServerName = Struct(
|
||||||
"",
|
"type" / Int8ub,
|
||||||
UBInt8("type"),
|
"name" / PascalString("length" / Int16ub),
|
||||||
PascalString("name", length_field=UBInt16("length")),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SNIExtension = Struct(
|
SNIExtension = Prefixed(
|
||||||
"",
|
Int16ub,
|
||||||
TunnelAdapter(
|
Struct(
|
||||||
PascalString("server_names", length_field=UBInt16("length")),
|
Int16ub,
|
||||||
TunnelAdapter(
|
"server_names" / GreedyRange(
|
||||||
PascalString("", length_field=UBInt16("length")),
|
"server_name" / Struct(
|
||||||
GreedyRange(ServerName)
|
"name_type" / Int8ub,
|
||||||
),
|
"host_name" / PascalString("length" / Int16ub),
|
||||||
),
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
ALPNExtension = Struct(
|
ALPNExtension = Prefixed(
|
||||||
"",
|
Int16ub,
|
||||||
TunnelAdapter(
|
Struct(
|
||||||
PascalString("alpn_protocols", length_field=UBInt16("length")),
|
Int16ub,
|
||||||
TunnelAdapter(
|
"alpn_protocols" / GreedyRange(
|
||||||
PascalString("", length_field=UBInt16("length")),
|
"name" / PascalString(Int8ub),
|
||||||
GreedyRange(PascalString("name"))
|
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
UnknownExtension = Struct(
|
UnknownExtension = Struct(
|
||||||
"",
|
"bytes" / PascalString("length" / Int16ub)
|
||||||
PascalString("bytes", length_field=UBInt16("extensions_length"))
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Extension = Struct(
|
Extension = "Extension" / Struct(
|
||||||
"Extension",
|
"type" / Int16ub,
|
||||||
UBInt16("type"),
|
Embedded(
|
||||||
Embed(
|
|
||||||
Switch(
|
Switch(
|
||||||
"", lambda ctx: ctx.type,
|
lambda ctx: ctx.type,
|
||||||
{
|
{
|
||||||
0x00: SNIExtension,
|
0x00: SNIExtension,
|
||||||
0x10: ALPNExtension
|
0x10: ALPNExtension,
|
||||||
},
|
},
|
||||||
default=UnknownExtension
|
default=UnknownExtension
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
extensions = TunnelAdapter(
|
extensions = "extensions" / Struct(
|
||||||
Optional(PascalString("extensions", length_field=UBInt16("extensions_length"))),
|
Int16ub,
|
||||||
OptionalGreedyRange(Extension)
|
"extensions" / GreedyRange(Extension)
|
||||||
)
|
)
|
||||||
|
|
||||||
ClientHello = Struct(
|
ClientHello = "ClientHello" / Struct(
|
||||||
"ClientHello",
|
|
||||||
ProtocolVersion,
|
ProtocolVersion,
|
||||||
Random,
|
Random,
|
||||||
SessionID,
|
SessionID,
|
||||||
@ -125,31 +127,27 @@ ClientHello = Struct(
|
|||||||
extensions,
|
extensions,
|
||||||
)
|
)
|
||||||
|
|
||||||
ServerHello = Struct(
|
ServerHello = "ServerHello" / Struct(
|
||||||
"ServerHello",
|
|
||||||
ProtocolVersion,
|
ProtocolVersion,
|
||||||
Random,
|
Random,
|
||||||
SessionID,
|
SessionID,
|
||||||
Bytes("cipher_suite", 2),
|
"cipher_suite" / Bytes(2),
|
||||||
UBInt8("compression_method"),
|
"compression_method" / Int8ub,
|
||||||
extensions,
|
extensions,
|
||||||
)
|
)
|
||||||
|
|
||||||
ClientCertificateType = Struct(
|
ClientCertificateType = "certificate_types" / Struct(
|
||||||
"certificate_types",
|
"length" / Int8ub, # TODO: Reject packets of length 0
|
||||||
UBInt8("length"), # TODO: Reject packets of length 0
|
Array(lambda ctx: ctx.length, "certificate_types" / Int8ub),
|
||||||
Array(lambda ctx: ctx.length, UBInt8("certificate_types")),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SignatureAndHashAlgorithm = Struct(
|
SignatureAndHashAlgorithm = "algorithms" / Struct(
|
||||||
"algorithms",
|
"hash" / Int8ub,
|
||||||
UBInt8("hash"),
|
"signature" / Int8ub,
|
||||||
UBInt8("signature"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SupportedSignatureAlgorithms = Struct(
|
SupportedSignatureAlgorithms = "supported_signature_algorithms" / Struct(
|
||||||
"supported_signature_algorithms",
|
"supported_signature_algorithms_length" / Int16ub,
|
||||||
UBInt16("supported_signature_algorithms_length"),
|
|
||||||
# TODO: Reject packets of length 0
|
# TODO: Reject packets of length 0
|
||||||
Array(
|
Array(
|
||||||
lambda ctx: ctx.supported_signature_algorithms_length / 2,
|
lambda ctx: ctx.supported_signature_algorithms_length / 2,
|
||||||
@ -157,56 +155,49 @@ SupportedSignatureAlgorithms = Struct(
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
DistinguishedName = Struct(
|
DistinguishedName = "certificate_authorities" / Struct(
|
||||||
"certificate_authorities",
|
"length" / Int16ub,
|
||||||
UBInt16("length"),
|
"certificate_authorities" / Bytes(lambda ctx: ctx.length),
|
||||||
Bytes("certificate_authorities", lambda ctx: ctx.length),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
CertificateRequest = Struct(
|
CertificateRequest = "CertificateRequest" / Struct(
|
||||||
"CertificateRequest",
|
|
||||||
ClientCertificateType,
|
ClientCertificateType,
|
||||||
SupportedSignatureAlgorithms,
|
SupportedSignatureAlgorithms,
|
||||||
DistinguishedName,
|
DistinguishedName,
|
||||||
)
|
)
|
||||||
|
|
||||||
ServerDHParams = Struct(
|
ServerDHParams = "ServerDHParams" / Struct(
|
||||||
"ServerDHParams",
|
"dh_p_length" / Int16ub,
|
||||||
UBInt16("dh_p_length"),
|
"dh_p" / Bytes(lambda ctx: ctx.dh_p_length),
|
||||||
Bytes("dh_p", lambda ctx: ctx.dh_p_length),
|
"dh_g_length" / Int16ub,
|
||||||
UBInt16("dh_g_length"),
|
"dh_g" / Bytes(lambda ctx: ctx.dh_g_length),
|
||||||
Bytes("dh_g", lambda ctx: ctx.dh_g_length),
|
"dh_Ys_length" / Int16ub,
|
||||||
UBInt16("dh_Ys_length"),
|
"dh_Ys" / Bytes(lambda ctx: ctx.dh_Ys_length),
|
||||||
Bytes("dh_Ys", lambda ctx: ctx.dh_Ys_length),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
PreMasterSecret = Struct(
|
PreMasterSecret = "pre_master_secret" / Struct(
|
||||||
"pre_master_secret",
|
|
||||||
ProtocolVersion,
|
ProtocolVersion,
|
||||||
Bytes("random_bytes", 46),
|
"random_bytes" / Bytes(46),
|
||||||
)
|
)
|
||||||
|
|
||||||
ASN1Cert = Struct(
|
ASN1Cert = "ASN1Cert" / Struct(
|
||||||
"ASN1Cert",
|
"length" / Int32ub, # TODO: Reject packets with length not in 1..2^24-1
|
||||||
UBInt32("length"), # TODO: Reject packets with length not in 1..2^24-1
|
"asn1_cert" / Bytes(lambda ctx: ctx.length),
|
||||||
Bytes("asn1_cert", lambda ctx: ctx.length),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Certificate = Struct(
|
Certificate = "Certificate" / Struct(
|
||||||
"Certificate", # TODO: Reject packets with length > 2 ** 24 - 1
|
# TODO: Reject packets with length > 2 ** 24 - 1
|
||||||
UBInt32("certificates_length"),
|
"certificates_length" / Int32ub,
|
||||||
Bytes("certificates_bytes", lambda ctx: ctx.certificates_length),
|
"certificates_bytes" / Bytes(lambda ctx: ctx.certificates_length),
|
||||||
)
|
)
|
||||||
|
|
||||||
Handshake = Struct(
|
Handshake = "Handshake" / Struct(
|
||||||
"Handshake",
|
"msg_type" / Int8ub,
|
||||||
UBInt8("msg_type"),
|
"length" / Int24ub,
|
||||||
UBInt24("length"),
|
"body" / Bytes(lambda ctx: ctx.length),
|
||||||
Bytes("body", lambda ctx: ctx.length),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Alert = Struct(
|
Alert = "Alert" / Struct(
|
||||||
"Alert",
|
"level" / Int8ub,
|
||||||
UBInt8("level"),
|
"description" / Int8ub,
|
||||||
UBInt8("description"),
|
|
||||||
)
|
)
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
# This file is dual licensed under the terms of the Apache License, Version
|
|
||||||
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
|
||||||
# for complete details.
|
|
||||||
|
|
||||||
|
|
||||||
import construct
|
|
||||||
|
|
||||||
class _UBInt24(construct.Adapter):
|
|
||||||
def _encode(self, obj, context):
|
|
||||||
return bytes(
|
|
||||||
(obj & 0xFF0000) >> 16,
|
|
||||||
(obj & 0x00FF00) >> 8,
|
|
||||||
obj & 0x0000FF
|
|
||||||
)
|
|
||||||
|
|
||||||
def _decode(self, obj, context):
|
|
||||||
obj = bytearray(obj)
|
|
||||||
return (obj[0] << 16 | obj[1] << 8 | obj[2])
|
|
||||||
|
|
||||||
|
|
||||||
def UBInt24(name): # noqa
|
|
||||||
return _UBInt24(construct.Bytes(name, 3))
|
|
@ -259,19 +259,19 @@ class TlsClientHello:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def sni(self):
|
def sni(self):
|
||||||
for extension in self._client_hello.extensions:
|
for extension in self._client_hello.extensions.extensions:
|
||||||
is_valid_sni_extension = (
|
is_valid_sni_extension = (
|
||||||
extension.type == 0x00 and
|
extension.type == 0x00 and
|
||||||
len(extension.server_names) == 1 and
|
len(extension.server_names) == 1 and
|
||||||
extension.server_names[0].type == 0 and
|
extension.server_names[0].name_type == 0 and
|
||||||
check.is_valid_host(extension.server_names[0].name)
|
check.is_valid_host(extension.server_names[0].host_name)
|
||||||
)
|
)
|
||||||
if is_valid_sni_extension:
|
if is_valid_sni_extension:
|
||||||
return extension.server_names[0].name.decode("idna")
|
return extension.server_names[0].host_name.decode("idna")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def alpn_protocols(self):
|
def alpn_protocols(self):
|
||||||
for extension in self._client_hello.extensions:
|
for extension in self._client_hello.extensions.extensions:
|
||||||
if extension.type == 0x10:
|
if extension.type == 0x10:
|
||||||
return list(extension.alpn_protocols)
|
return list(extension.alpn_protocols)
|
||||||
|
|
||||||
|
2
setup.py
2
setup.py
@ -63,7 +63,7 @@ setup(
|
|||||||
"click>=6.2, <7.0",
|
"click>=6.2, <7.0",
|
||||||
"certifi>=2015.11.20.1", # no semver here - this should always be on the last release!
|
"certifi>=2015.11.20.1", # no semver here - this should always be on the last release!
|
||||||
"configargparse>=0.10, <0.12",
|
"configargparse>=0.10, <0.12",
|
||||||
"construct>=2.5.2, <2.6",
|
"construct>=2.8, <2.9",
|
||||||
"cryptography>=1.3, <1.7",
|
"cryptography>=1.3, <1.7",
|
||||||
"cssutils>=1.0.1, <1.1",
|
"cssutils>=1.0.1, <1.1",
|
||||||
"Flask>=0.10.1, <0.12",
|
"Flask>=0.10.1, <0.12",
|
||||||
|
Loading…
Reference in New Issue
Block a user