mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-27 02:24:18 +00:00
adjust to netlib api changes
This commit is contained in:
parent
9cc83ed9a8
commit
a0c8b20b7d
@ -82,7 +82,7 @@ class Pathoc(tcp.TCPClient):
|
|||||||
r = language.parse_request(self.settings, spec)
|
r = language.parse_request(self.settings, spec)
|
||||||
language.serve(r, self.wfile, self.settings, self.address.host)
|
language.serve(r, self.wfile, self.settings, self.address.host)
|
||||||
self.wfile.flush()
|
self.wfile.flush()
|
||||||
ret = list(http.read_response(self.rfile, r.method, None))
|
ret = list(http.read_response(self.rfile, r.method.string(), None))
|
||||||
ret.append(self.sslinfo)
|
ret.append(self.sslinfo)
|
||||||
return Response(*ret)
|
return Response(*ret)
|
||||||
|
|
||||||
@ -134,9 +134,9 @@ class Pathoc(tcp.TCPClient):
|
|||||||
try:
|
try:
|
||||||
req = language.serve(r, self.wfile, self.settings, self.address.host)
|
req = language.serve(r, self.wfile, self.settings, self.address.host)
|
||||||
self.wfile.flush()
|
self.wfile.flush()
|
||||||
resp = http.read_response(self.rfile, r.method, None)
|
resp = http.read_response(self.rfile, r.method.string(), None)
|
||||||
except http.HttpError, v:
|
except http.HttpError, v:
|
||||||
print >> fp, "<< HTTP Error:", v.msg
|
print >> fp, "<< HTTP Error:", v.message
|
||||||
except tcp.NetLibTimeout:
|
except tcp.NetLibTimeout:
|
||||||
if ignoretimeout:
|
if ignoretimeout:
|
||||||
return
|
return
|
||||||
|
@ -11,13 +11,14 @@ CA_CERT_NAME = "mitmproxy-ca.pem"
|
|||||||
|
|
||||||
logger = logging.getLogger('pathod')
|
logger = logging.getLogger('pathod')
|
||||||
|
|
||||||
|
|
||||||
class PathodError(Exception): pass
|
class PathodError(Exception): pass
|
||||||
|
|
||||||
|
|
||||||
class SSLOptions:
|
class SSLOptions:
|
||||||
def __init__(self, confdir=CONFDIR, cn=None, not_after_connect=None,
|
def __init__(self, confdir=CONFDIR, cn=None, not_after_connect=None,
|
||||||
request_client_cert=False, sslversion=tcp.SSLv23_METHOD,
|
request_client_cert=False, sslversion=tcp.SSLv23_METHOD,
|
||||||
ciphers=None, certs=None):
|
ciphers=None, certs=None):
|
||||||
self.confdir = confdir
|
self.confdir = confdir
|
||||||
self.cn = cn
|
self.cn = cn
|
||||||
self.certstore = certutils.CertStore.from_store(
|
self.certstore = certutils.CertStore.from_store(
|
||||||
@ -39,12 +40,12 @@ class SSLOptions:
|
|||||||
return self.certstore.get_cert(name, [])
|
return self.certstore.get_cert(name, [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PathodHandler(tcp.BaseHandler):
|
class PathodHandler(tcp.BaseHandler):
|
||||||
wbufsize = 0
|
wbufsize = 0
|
||||||
sni = None
|
sni = None
|
||||||
|
|
||||||
def info(self, s):
|
def info(self, s):
|
||||||
logger.info("%s:%s: %s"%(self.address.host, self.address.port, str(s)))
|
logger.info("%s:%s: %s" % (self.address.host, self.address.port, str(s)))
|
||||||
|
|
||||||
def handle_sni(self, connection):
|
def handle_sni(self, connection):
|
||||||
self.sni = connection.get_servername()
|
self.sni = connection.get_servername()
|
||||||
@ -55,14 +56,14 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
err = language.make_error_response(c)
|
err = language.make_error_response(c)
|
||||||
language.serve(err, self.wfile, self.server.request_settings)
|
language.serve(err, self.wfile, self.server.request_settings)
|
||||||
log = dict(
|
log = dict(
|
||||||
type = "error",
|
type="error",
|
||||||
msg = c
|
msg=c
|
||||||
)
|
)
|
||||||
return False, log
|
return False, log
|
||||||
|
|
||||||
if self.server.explain and not isinstance(crafted, language.PathodErrorResponse):
|
if self.server.explain and not isinstance(crafted, language.PathodErrorResponse):
|
||||||
crafted = crafted.freeze(self.server.request_settings, None)
|
crafted = crafted.freeze(self.server.request_settings, None)
|
||||||
self.info(">> Spec: %s"%crafted.spec())
|
self.info(">> Spec: %s" % crafted.spec())
|
||||||
response_log = language.serve(crafted, self.wfile, self.server.request_settings, None)
|
response_log = language.serve(crafted, self.wfile, self.server.request_settings, None)
|
||||||
if response_log["disconnect"]:
|
if response_log["disconnect"]:
|
||||||
return False, response_log
|
return False, response_log
|
||||||
@ -76,7 +77,7 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
log: A dictionary, or None
|
log: A dictionary, or None
|
||||||
"""
|
"""
|
||||||
line = self.rfile.readline()
|
line = self.rfile.readline()
|
||||||
if line == "\r\n" or line == "\n": # Possible leftover from previous message
|
if line == "\r\n" or line == "\n": # Possible leftover from previous message
|
||||||
line = self.rfile.readline()
|
line = self.rfile.readline()
|
||||||
if line == "":
|
if line == "":
|
||||||
# Normal termination
|
# Normal termination
|
||||||
@ -86,103 +87,104 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
if m(http.parse_init_connect(line)):
|
if m(http.parse_init_connect(line)):
|
||||||
headers = http.read_headers(self.rfile)
|
headers = http.read_headers(self.rfile)
|
||||||
self.wfile.write(
|
self.wfile.write(
|
||||||
'HTTP/1.1 200 Connection established\r\n' +
|
'HTTP/1.1 200 Connection established\r\n' +
|
||||||
('Proxy-agent: %s\r\n'%version.NAMEVERSION) +
|
('Proxy-agent: %s\r\n' % version.NAMEVERSION) +
|
||||||
'\r\n'
|
'\r\n'
|
||||||
)
|
)
|
||||||
self.wfile.flush()
|
self.wfile.flush()
|
||||||
if not self.server.ssloptions.not_after_connect:
|
if not self.server.ssloptions.not_after_connect:
|
||||||
try:
|
try:
|
||||||
cert, key = self.server.ssloptions.get_cert(m.v[0])
|
cert, key = self.server.ssloptions.get_cert(m.v[0])
|
||||||
self.convert_to_ssl(
|
self.convert_to_ssl(
|
||||||
cert, key,
|
cert, key,
|
||||||
handle_sni = self.handle_sni,
|
handle_sni=self.handle_sni,
|
||||||
request_client_cert = self.server.ssloptions.request_client_cert,
|
request_client_cert=self.server.ssloptions.request_client_cert,
|
||||||
cipher_list = self.server.ssloptions.ciphers,
|
cipher_list=self.server.ssloptions.ciphers,
|
||||||
method = self.server.ssloptions.sslversion,
|
method=self.server.ssloptions.sslversion,
|
||||||
)
|
)
|
||||||
except tcp.NetLibError, v:
|
except tcp.NetLibError, v:
|
||||||
s = str(v)
|
s = str(v)
|
||||||
self.info(s)
|
self.info(s)
|
||||||
return False, dict(type = "error", msg = s)
|
return False, dict(type="error", msg=s)
|
||||||
return True, None
|
return True, None
|
||||||
elif m(http.parse_init_proxy(line)):
|
elif m(http.parse_init_proxy(line)):
|
||||||
method, _, _, _, path, httpversion = m.v
|
method, _, _, _, path, httpversion = m.v
|
||||||
elif m(http.parse_init_http(line)):
|
elif m(http.parse_init_http(line)):
|
||||||
method, path, httpversion = m.v
|
method, path, httpversion = m.v
|
||||||
else:
|
else:
|
||||||
s = "Invalid first line: %s"%repr(line)
|
s = "Invalid first line: %s" % repr(line)
|
||||||
self.info(s)
|
self.info(s)
|
||||||
return False, dict(type = "error", msg = s)
|
return False, dict(type="error", msg=s)
|
||||||
|
|
||||||
headers = http.read_headers(self.rfile)
|
headers = http.read_headers(self.rfile)
|
||||||
if headers is None:
|
if headers is None:
|
||||||
s = "Invalid headers"
|
s = "Invalid headers"
|
||||||
self.info(s)
|
self.info(s)
|
||||||
return False, dict(type = "error", msg = s)
|
return False, dict(type="error", msg=s)
|
||||||
|
|
||||||
clientcert = None
|
clientcert = None
|
||||||
if self.clientcert:
|
if self.clientcert:
|
||||||
clientcert = dict(
|
clientcert = dict(
|
||||||
cn = self.clientcert.cn,
|
cn=self.clientcert.cn,
|
||||||
subject = self.clientcert.subject,
|
subject=self.clientcert.subject,
|
||||||
serial = self.clientcert.serial,
|
serial=self.clientcert.serial,
|
||||||
notbefore = self.clientcert.notbefore.isoformat(),
|
notbefore=self.clientcert.notbefore.isoformat(),
|
||||||
notafter = self.clientcert.notafter.isoformat(),
|
notafter=self.clientcert.notafter.isoformat(),
|
||||||
keyinfo = self.clientcert.keyinfo,
|
keyinfo=self.clientcert.keyinfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
retlog = dict(
|
retlog = dict(
|
||||||
type = "crafted",
|
type="crafted",
|
||||||
request = dict(
|
request=dict(
|
||||||
path = path,
|
path=path,
|
||||||
method = method,
|
method=method,
|
||||||
headers = headers.lst,
|
headers=headers.lst,
|
||||||
httpversion = httpversion,
|
httpversion=httpversion,
|
||||||
sni = self.sni,
|
sni=self.sni,
|
||||||
remote_address = self.address(),
|
remote_address=self.address(),
|
||||||
clientcert = clientcert,
|
clientcert=clientcert,
|
||||||
),
|
),
|
||||||
cipher = None,
|
cipher=None,
|
||||||
)
|
)
|
||||||
if self.ssl_established:
|
if self.ssl_established:
|
||||||
retlog["cipher"] = self.get_current_cipher()
|
retlog["cipher"] = self.get_current_cipher()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
content = http.read_http_body(
|
content = http.read_http_body(
|
||||||
self.rfile, headers, None, True
|
self.rfile, headers, None,
|
||||||
)
|
method, None, True
|
||||||
|
)
|
||||||
except http.HttpError, s:
|
except http.HttpError, s:
|
||||||
s = str(s)
|
s = str(s)
|
||||||
self.info(s)
|
self.info(s)
|
||||||
return False, dict(type = "error", msg = s)
|
return False, dict(type="error", msg=s)
|
||||||
|
|
||||||
for i in self.server.anchors:
|
for i in self.server.anchors:
|
||||||
if i[0].match(path):
|
if i[0].match(path):
|
||||||
self.info("crafting anchor: %s"%path)
|
self.info("crafting anchor: %s" % path)
|
||||||
aresp = language.parse_response(self.server.request_settings, i[1])
|
aresp = language.parse_response(self.server.request_settings, i[1])
|
||||||
again, retlog["response"] = self.serve_crafted(aresp)
|
again, retlog["response"] = self.serve_crafted(aresp)
|
||||||
return again, retlog
|
return again, retlog
|
||||||
|
|
||||||
if not self.server.nocraft and path.startswith(self.server.craftanchor):
|
if not self.server.nocraft and path.startswith(self.server.craftanchor):
|
||||||
spec = urllib.unquote(path)[len(self.server.craftanchor):]
|
spec = urllib.unquote(path)[len(self.server.craftanchor):]
|
||||||
self.info("crafting spec: %s"%spec)
|
self.info("crafting spec: %s" % spec)
|
||||||
try:
|
try:
|
||||||
crafted = language.parse_response(self.server.request_settings, spec)
|
crafted = language.parse_response(self.server.request_settings, spec)
|
||||||
except language.ParseException, v:
|
except language.ParseException, v:
|
||||||
self.info("Parse error: %s"%v.msg)
|
self.info("Parse error: %s" % v.msg)
|
||||||
crafted = language.make_error_response(
|
crafted = language.make_error_response(
|
||||||
"Parse Error",
|
"Parse Error",
|
||||||
"Error parsing response spec: %s\n"%v.msg + v.marked()
|
"Error parsing response spec: %s\n" % v.msg + v.marked()
|
||||||
)
|
)
|
||||||
again, retlog["response"] = self.serve_crafted(crafted)
|
again, retlog["response"] = self.serve_crafted(crafted)
|
||||||
return again, retlog
|
return again, retlog
|
||||||
elif self.server.noweb:
|
elif self.server.noweb:
|
||||||
crafted = language.make_error_response("Access Denied")
|
crafted = language.make_error_response("Access Denied")
|
||||||
language.serve(crafted, self.wfile, self.server.request_settings)
|
language.serve(crafted, self.wfile, self.server.request_settings)
|
||||||
return False, dict(type = "error", msg="Access denied: web interface disabled")
|
return False, dict(type="error", msg="Access denied: web interface disabled")
|
||||||
else:
|
else:
|
||||||
self.info("app: %s %s"%(method, path))
|
self.info("app: %s %s" % (method, path))
|
||||||
cc = wsgi.ClientConn(self.address())
|
cc = wsgi.ClientConn(self.address())
|
||||||
req = wsgi.Request(cc, "http", method, path, headers, content)
|
req = wsgi.Request(cc, "http", method, path, headers, content)
|
||||||
sn = self.connection.getsockname()
|
sn = self.connection.getsockname()
|
||||||
@ -198,11 +200,11 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
def _log_bytes(self, header, data, hexdump):
|
def _log_bytes(self, header, data, hexdump):
|
||||||
s = []
|
s = []
|
||||||
if hexdump:
|
if hexdump:
|
||||||
s.append("%s (hex dump):"%header)
|
s.append("%s (hex dump):" % header)
|
||||||
for line in netlib.utils.hexdump(data):
|
for line in netlib.utils.hexdump(data):
|
||||||
s.append("\t%s %s %s"%line)
|
s.append("\t%s %s %s" % line)
|
||||||
else:
|
else:
|
||||||
s.append("%s (unprintables escaped):"%header)
|
s.append("%s (unprintables escaped):" % header)
|
||||||
s.append(netlib.utils.cleanBin(data))
|
s.append(netlib.utils.cleanBin(data))
|
||||||
self.info("\n".join(s))
|
self.info("\n".join(s))
|
||||||
|
|
||||||
@ -212,17 +214,17 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
cert, key = self.server.ssloptions.get_cert(None)
|
cert, key = self.server.ssloptions.get_cert(None)
|
||||||
self.convert_to_ssl(
|
self.convert_to_ssl(
|
||||||
cert, key,
|
cert, key,
|
||||||
handle_sni = self.handle_sni,
|
handle_sni=self.handle_sni,
|
||||||
request_client_cert = self.server.ssloptions.request_client_cert,
|
request_client_cert=self.server.ssloptions.request_client_cert,
|
||||||
cipher_list = self.server.ssloptions.ciphers,
|
cipher_list=self.server.ssloptions.ciphers,
|
||||||
method = self.server.ssloptions.sslversion,
|
method=self.server.ssloptions.sslversion,
|
||||||
)
|
)
|
||||||
except tcp.NetLibError, v:
|
except tcp.NetLibError, v:
|
||||||
s = str(v)
|
s = str(v)
|
||||||
self.server.add_log(
|
self.server.add_log(
|
||||||
dict(
|
dict(
|
||||||
type = "error",
|
type="error",
|
||||||
msg = s
|
msg=s
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.info(s)
|
self.info(s)
|
||||||
@ -248,13 +250,14 @@ class PathodHandler(tcp.BaseHandler):
|
|||||||
|
|
||||||
class Pathod(tcp.TCPServer):
|
class Pathod(tcp.TCPServer):
|
||||||
LOGBUF = 500
|
LOGBUF = 500
|
||||||
def __init__(
|
|
||||||
self, addr, confdir=CONFDIR, ssl=False, ssloptions=None,
|
def __init__(
|
||||||
craftanchor="/p/", staticdir=None, anchors=None,
|
self, addr, confdir=CONFDIR, ssl=False, ssloptions=None,
|
||||||
sizelimit=None, noweb=False, nocraft=False, noapi=False,
|
craftanchor="/p/", staticdir=None, anchors=None,
|
||||||
nohang=False, timeout=None, logreq=False, logresp=False,
|
sizelimit=None, noweb=False, nocraft=False, noapi=False,
|
||||||
explain=False, hexdump=False
|
nohang=False, timeout=None, logreq=False, logresp=False,
|
||||||
):
|
explain=False, hexdump=False
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
addr: (address, port) tuple. If port is 0, a free port will be
|
addr: (address, port) tuple. If port is 0, a free port will be
|
||||||
automatically chosen.
|
automatically chosen.
|
||||||
@ -287,11 +290,11 @@ class Pathod(tcp.TCPServer):
|
|||||||
try:
|
try:
|
||||||
arex = re.compile(i[0])
|
arex = re.compile(i[0])
|
||||||
except re.error:
|
except re.error:
|
||||||
raise PathodError("Invalid regex in anchor: %s"%i[0])
|
raise PathodError("Invalid regex in anchor: %s" % i[0])
|
||||||
try:
|
try:
|
||||||
language.parse_response(self.request_settings, i[1])
|
language.parse_response(self.request_settings, i[1])
|
||||||
except language.ParseException, v:
|
except language.ParseException, v:
|
||||||
raise PathodError("Invalid page spec in anchor: '%s', %s"%(i[1], str(v)))
|
raise PathodError("Invalid page spec in anchor: '%s', %s" % (i[1], str(v)))
|
||||||
self.anchors.append((arex, i[1]))
|
self.anchors.append((arex, i[1]))
|
||||||
|
|
||||||
def check_policy(self, req, settings):
|
def check_policy(self, req, settings):
|
||||||
@ -311,7 +314,7 @@ class Pathod(tcp.TCPServer):
|
|||||||
@property
|
@property
|
||||||
def request_settings(self):
|
def request_settings(self):
|
||||||
return dict(
|
return dict(
|
||||||
staticdir = self.staticdir
|
staticdir=self.staticdir
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle_client_connection(self, request, client_address):
|
def handle_client_connection(self, request, client_address):
|
||||||
@ -319,12 +322,12 @@ class Pathod(tcp.TCPServer):
|
|||||||
try:
|
try:
|
||||||
h.handle()
|
h.handle()
|
||||||
h.finish()
|
h.finish()
|
||||||
except tcp.NetLibDisconnect: # pragma: no cover
|
except tcp.NetLibDisconnect: # pragma: no cover
|
||||||
h.info("Disconnect")
|
h.info("Disconnect")
|
||||||
self.add_log(
|
self.add_log(
|
||||||
dict(
|
dict(
|
||||||
type = "error",
|
type="error",
|
||||||
msg = "Disconnect"
|
msg="Disconnect"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
@ -332,7 +335,7 @@ class Pathod(tcp.TCPServer):
|
|||||||
h.info("Timeout")
|
h.info("Timeout")
|
||||||
self.add_log(
|
self.add_log(
|
||||||
dict(
|
dict(
|
||||||
type = "timeout",
|
type="timeout",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user