From c048ae1d5b652ad4778917e624ace217e1ecfd91 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Thu, 7 Jul 2016 18:37:33 -0700 Subject: [PATCH] remove context from all scripts --- examples/add_header.py | 2 +- examples/change_upstream_proxy.py | 2 +- examples/custom_contentviews.py | 8 ++-- examples/dns_spoofing.py | 2 +- examples/dup_and_replay.py | 9 ++-- examples/fail_with_500.py | 2 +- examples/filt.py | 10 +++-- examples/flowwriter.py | 10 +++-- examples/har_extractor.py | 12 ++++-- examples/iframe_injector.py | 14 ++++--- examples/modify_form.py | 2 +- examples/modify_querystring.py | 2 +- examples/modify_response_body.py | 14 ++++--- examples/nonblocking.py | 7 ++-- examples/proxapp.py | 7 ++-- examples/redirect_requests.py | 2 +- examples/sslstrip.py | 14 +++---- examples/stream.py | 2 +- examples/stream_modify.py | 2 +- examples/stub.py | 41 ++++++++++--------- examples/tcp_message.py | 2 +- examples/tls_passthrough.py | 24 ++++++----- examples/upsidedownternet.py | 2 +- test/mitmproxy/data/scripts/a.py | 4 +- test/mitmproxy/data/scripts/all.py | 29 ++++++------- .../data/scripts/concurrent_decorator.py | 2 +- .../data/scripts/concurrent_decorator_err.py | 2 +- test/mitmproxy/data/scripts/duplicate_flow.py | 8 ++-- test/mitmproxy/data/scripts/reqerr.py | 4 +- test/mitmproxy/data/scripts/starterr.py | 2 +- test/mitmproxy/data/scripts/stream_modify.py | 2 +- .../data/scripts/tcp_stream_modify.py | 2 +- test/mitmproxy/data/scripts/unloaderr.py | 2 +- 33 files changed, 137 insertions(+), 112 deletions(-) diff --git a/examples/add_header.py b/examples/add_header.py index cf1b53cc8..3e0b5f1e3 100644 --- a/examples/add_header.py +++ b/examples/add_header.py @@ -1,2 +1,2 @@ -def response(context, flow): +def response(flow): flow.response.headers["newheader"] = "foo" diff --git a/examples/change_upstream_proxy.py b/examples/change_upstream_proxy.py index 34a6eece0..49d5379f6 100644 --- a/examples/change_upstream_proxy.py +++ b/examples/change_upstream_proxy.py @@ -14,7 +14,7 @@ def proxy_address(flow): return ("localhost", 8081) -def request(context, flow): +def request(flow): if flow.request.method == "CONNECT": # If the decision is done by domain, one could also modify the server address here. # We do it after CONNECT here to have the request data available as well. diff --git a/examples/custom_contentviews.py b/examples/custom_contentviews.py index 92fb6a580..5a63e2a05 100644 --- a/examples/custom_contentviews.py +++ b/examples/custom_contentviews.py @@ -62,9 +62,9 @@ class ViewPigLatin(contentviews.View): pig_view = ViewPigLatin() -def start(context): - context.add_contentview(pig_view) +def start(): + contentviews.add(pig_view) -def done(context): - context.remove_contentview(pig_view) +def done(): + contentviews.remove(pig_view) diff --git a/examples/dns_spoofing.py b/examples/dns_spoofing.py index 8d715f339..c020047f8 100644 --- a/examples/dns_spoofing.py +++ b/examples/dns_spoofing.py @@ -28,7 +28,7 @@ import re parse_host_header = re.compile(r"^(?P[^:]+|\[.+\])(?::(?P\d+))?$") -def request(context, flow): +def request(flow): if flow.client_conn.ssl_established: flow.request.scheme = "https" sni = flow.client_conn.connection.get_servername() diff --git a/examples/dup_and_replay.py b/examples/dup_and_replay.py index 9ba91d3bf..b47bf951d 100644 --- a/examples/dup_and_replay.py +++ b/examples/dup_and_replay.py @@ -1,4 +1,7 @@ -def request(context, flow): - f = context.duplicate_flow(flow) +from mitmproxy import master + + +def request(flow): + f = master.duplicate_flow(flow) f.request.path = "/changed" - context.replay_request(f) + master.replay_request(f, block=True, run_scripthooks=False) diff --git a/examples/fail_with_500.py b/examples/fail_with_500.py index aec85b50b..9710f74a0 100644 --- a/examples/fail_with_500.py +++ b/examples/fail_with_500.py @@ -1,3 +1,3 @@ -def response(context, flow): +def response(flow): flow.response.status_code = 500 flow.response.content = b"" diff --git a/examples/filt.py b/examples/filt.py index 1a423845c..21744edd8 100644 --- a/examples/filt.py +++ b/examples/filt.py @@ -3,14 +3,16 @@ import sys from mitmproxy import filt +state = {} -def start(context): + +def start(): if len(sys.argv) != 2: raise ValueError("Usage: -s 'filt.py FILTER'") - context.filter = filt.parse(sys.argv[1]) + state["filter"] = filt.parse(sys.argv[1]) -def response(context, flow): - if flow.match(context.filter): +def response(flow): + if flow.match(state["filter"]): print("Flow matches filter:") print(flow) diff --git a/examples/flowwriter.py b/examples/flowwriter.py index cb5ccb0dc..07c7ca200 100644 --- a/examples/flowwriter.py +++ b/examples/flowwriter.py @@ -3,8 +3,10 @@ import sys from mitmproxy.flow import FlowWriter +state = {} -def start(context): + +def start(): if len(sys.argv) != 2: raise ValueError('Usage: -s "flowriter.py filename"') @@ -12,9 +14,9 @@ def start(context): f = sys.stdout else: f = open(sys.argv[1], "wb") - context.flow_writer = FlowWriter(f) + state["flow_writer"] = FlowWriter(f) -def response(context, flow): +def response(flow): if random.choice([True, False]): - context.flow_writer.add(flow) + state["flow_writer"].add(flow) diff --git a/examples/har_extractor.py b/examples/har_extractor.py index a5c055192..b136bd402 100644 --- a/examples/har_extractor.py +++ b/examples/har_extractor.py @@ -54,7 +54,13 @@ class _HARLog(HAR.log): return self.__page_list__ -def start(context): +class Context(object): + pass + +context = Context() + + +def start(): """ On start we create a HARLog instance. You will have to adapt this to suit your actual needs of HAR generation. As it will probably be @@ -79,7 +85,7 @@ def start(context): context.seen_server = set() -def response(context, flow): +def response(flow): """ Called when a server response has been received. At the time of this message both a request and a response are present and completely done. @@ -201,7 +207,7 @@ def response(context, flow): context.HARLog.add(entry) -def done(context): +def done(): """ Called once on script shutdown, after any other events. """ diff --git a/examples/iframe_injector.py b/examples/iframe_injector.py index ebb5fd023..70247d311 100644 --- a/examples/iframe_injector.py +++ b/examples/iframe_injector.py @@ -4,25 +4,27 @@ import sys from bs4 import BeautifulSoup from mitmproxy.models import decoded +iframe_url = None -def start(context): + +def start(): if len(sys.argv) != 2: raise ValueError('Usage: -s "iframe_injector.py url"') - context.iframe_url = sys.argv[1] + global iframe_url + iframe_url = sys.argv[1] -def response(context, flow): - if flow.request.host in context.iframe_url: +def response(flow): + if flow.request.host in iframe_url: return with decoded(flow.response): # Remove content encoding (gzip, ...) html = BeautifulSoup(flow.response.content, "lxml") if html.body: iframe = html.new_tag( "iframe", - src=context.iframe_url, + src=iframe_url, frameborder=0, height=0, width=0) html.body.insert(0, iframe) flow.response.content = str(html).encode("utf8") - context.log("Iframe inserted.") diff --git a/examples/modify_form.py b/examples/modify_form.py index 3fe0cf964..b63a15860 100644 --- a/examples/modify_form.py +++ b/examples/modify_form.py @@ -1,4 +1,4 @@ -def request(context, flow): +def request(flow): if flow.request.urlencoded_form: flow.request.urlencoded_form["mitmproxy"] = "rocks" else: diff --git a/examples/modify_querystring.py b/examples/modify_querystring.py index b89e5c8dc..ee8a89ad8 100644 --- a/examples/modify_querystring.py +++ b/examples/modify_querystring.py @@ -1,2 +1,2 @@ -def request(context, flow): +def request(flow): flow.request.query["mitmproxy"] = "rocks" diff --git a/examples/modify_response_body.py b/examples/modify_response_body.py index 994932a1e..23ad01511 100644 --- a/examples/modify_response_body.py +++ b/examples/modify_response_body.py @@ -5,16 +5,20 @@ import sys from mitmproxy.models import decoded -def start(context): +state = {} + + +def start(): if len(sys.argv) != 3: raise ValueError('Usage: -s "modify_response_body.py old new"') # You may want to use Python's argparse for more sophisticated argument # parsing. - context.old, context.new = sys.argv[1].encode(), sys.argv[2].encode() + state["old"], state["new"] = sys.argv[1].encode(), sys.argv[2].encode() -def response(context, flow): +def response(flow): with decoded(flow.response): # automatically decode gzipped responses. flow.response.content = flow.response.content.replace( - context.old, - context.new) + state["old"], + state["new"] + ) diff --git a/examples/nonblocking.py b/examples/nonblocking.py index 4609f389a..05a269210 100644 --- a/examples/nonblocking.py +++ b/examples/nonblocking.py @@ -1,9 +1,10 @@ import time +import mitmproxy from mitmproxy.script import concurrent @concurrent # Remove this and see what happens -def request(context, flow): - context.log("handle request: %s%s" % (flow.request.host, flow.request.path)) +def request(flow): + mitmproxy.log("handle request: %s%s" % (flow.request.host, flow.request.path)) time.sleep(5) - context.log("start request: %s%s" % (flow.request.host, flow.request.path)) + mitmproxy.log("start request: %s%s" % (flow.request.host, flow.request.path)) diff --git a/examples/proxapp.py b/examples/proxapp.py index 613d3f8b0..ddc385448 100644 --- a/examples/proxapp.py +++ b/examples/proxapp.py @@ -4,6 +4,7 @@ instance, we're using the Flask framework (http://flask.pocoo.org/) to expose a single simplest-possible page. """ from flask import Flask +import mitmproxy app = Flask("proxapp") @@ -15,10 +16,10 @@ def hello_world(): # Register the app using the magic domain "proxapp" on port 80. Requests to # this domain and port combination will now be routed to the WSGI app instance. -def start(context): - context.app_registry.add(app, "proxapp", 80) +def start(): + mitmproxy.master.apps.add(app, "proxapp", 80) # SSL works too, but the magic domain needs to be resolvable from the mitmproxy machine due to mitmproxy's design. # mitmproxy will connect to said domain and use serve its certificate (unless --no-upstream-cert is set) # but won't send any data. - context.app_registry.add(app, "example.com", 443) + mitmproxy.master.apps.add(app, "example.com", 443) diff --git a/examples/redirect_requests.py b/examples/redirect_requests.py index af2aa9075..36594bcd8 100644 --- a/examples/redirect_requests.py +++ b/examples/redirect_requests.py @@ -5,7 +5,7 @@ from mitmproxy.models import HTTPResponse from netlib.http import Headers -def request(context, flow): +def request(flow): # pretty_host takes the "Host" header of the request into account, # which is useful in transparent mode where we usually only have the IP # otherwise. diff --git a/examples/sslstrip.py b/examples/sslstrip.py index 8dde8e3ef..afc95fc8e 100644 --- a/examples/sslstrip.py +++ b/examples/sslstrip.py @@ -2,23 +2,21 @@ from netlib.http import decoded import re from six.moves import urllib - -def start(context): - # set of SSL/TLS capable hosts - context.secure_hosts = set() +# set of SSL/TLS capable hosts +secure_hosts = set() -def request(context, flow): +def request(flow): flow.request.headers.pop('If-Modified-Since', None) flow.request.headers.pop('Cache-Control', None) # proxy connections to SSL-enabled hosts - if flow.request.pretty_host in context.secure_hosts: + if flow.request.pretty_host in secure_hosts: flow.request.scheme = 'https' flow.request.port = 443 -def response(context, flow): +def response(flow): with decoded(flow.response): flow.request.headers.pop('Strict-Transport-Security', None) flow.request.headers.pop('Public-Key-Pins', None) @@ -31,7 +29,7 @@ def response(context, flow): location = flow.response.headers['Location'] hostname = urllib.parse.urlparse(location).hostname if hostname: - context.secure_hosts.add(hostname) + secure_hosts.add(hostname) flow.response.headers['Location'] = location.replace('https://', 'http://', 1) # strip secure flag from 'Set-Cookie' headers diff --git a/examples/stream.py b/examples/stream.py index 3adbe4372..8598f329c 100644 --- a/examples/stream.py +++ b/examples/stream.py @@ -1,4 +1,4 @@ -def responseheaders(context, flow): +def responseheaders(flow): """ Enables streaming for all responses. """ diff --git a/examples/stream_modify.py b/examples/stream_modify.py index aa395c03f..5e5da95bd 100644 --- a/examples/stream_modify.py +++ b/examples/stream_modify.py @@ -16,5 +16,5 @@ def modify(chunks): yield chunk.replace("foo", "bar") -def responseheaders(context, flow): +def responseheaders(flow): flow.response.stream = modify diff --git a/examples/stub.py b/examples/stub.py index a0f73538e..a4f16699c 100644 --- a/examples/stub.py +++ b/examples/stub.py @@ -1,79 +1,80 @@ +import mitmproxy """ This is a script stub, with definitions for all events. """ -def start(context): +def start(): """ Called once on script startup, before any other events. """ - context.log("start") + mitmproxy.log("start") -def clientconnect(context, root_layer): +def clientconnect(root_layer): """ Called when a client initiates a connection to the proxy. Note that a connection can correspond to multiple HTTP requests """ - context.log("clientconnect") + mitmproxy.log("clientconnect") -def request(context, flow): +def request(flow): """ Called when a client request has been received. """ - context.log("request") + mitmproxy.log("request") -def serverconnect(context, server_conn): +def serverconnect(server_conn): """ Called when the proxy initiates a connection to the target server. Note that a connection can correspond to multiple HTTP requests """ - context.log("serverconnect") + mitmproxy.log("serverconnect") -def responseheaders(context, flow): +def responseheaders(flow): """ Called when the response headers for a server response have been received, but the response body has not been processed yet. Can be used to tell mitmproxy to stream the response. """ - context.log("responseheaders") + mitmproxy.log("responseheaders") -def response(context, flow): +def response(flow): """ Called when a server response has been received. """ - context.log("response") + mitmproxy.log("response") -def error(context, flow): +def error(flow): """ Called when a flow error has occured, e.g. invalid server responses, or interrupted connections. This is distinct from a valid server HTTP error response, which is simply a response with an HTTP error code. """ - context.log("error") + mitmproxy.log("error") -def serverdisconnect(context, server_conn): +def serverdisconnect(server_conn): """ Called when the proxy closes the connection to the target server. """ - context.log("serverdisconnect") + mitmproxy.log("serverdisconnect") -def clientdisconnect(context, root_layer): +def clientdisconnect(root_layer): """ Called when a client disconnects from the proxy. """ - context.log("clientdisconnect") + mitmproxy.log("clientdisconnect") -def done(context): +def done(): """ Called once on script shutdown, after any other events. """ - context.log("done") + mitmproxy.log("done") diff --git a/examples/tcp_message.py b/examples/tcp_message.py index 6eced0dc0..b431c23f6 100644 --- a/examples/tcp_message.py +++ b/examples/tcp_message.py @@ -11,7 +11,7 @@ mitmdump -T --host --tcp ".*" -q -s examples/tcp_message.py from netlib import strutils -def tcp_message(ctx, tcp_msg): +def tcp_message(tcp_msg): modified_msg = tcp_msg.message.replace("foo", "bar") is_modified = False if modified_msg == tcp_msg.message else True diff --git a/examples/tls_passthrough.py b/examples/tls_passthrough.py index 50aab65b0..374020e7e 100644 --- a/examples/tls_passthrough.py +++ b/examples/tls_passthrough.py @@ -20,13 +20,14 @@ Example: Authors: Maximilian Hils, Matthew Tuusberg """ -from __future__ import (absolute_import, print_function, division) +from __future__ import absolute_import, print_function, division import collections import random import sys from enum import Enum +import mitmproxy from mitmproxy.exceptions import TlsProtocolException from mitmproxy.protocol import TlsLayer, RawTCPLayer @@ -97,7 +98,6 @@ class TlsFeedback(TlsLayer): def _establish_tls_with_client(self): server_address = self.server_conn.address - tls_strategy = self.script_context.tls_strategy try: super(TlsFeedback, self)._establish_tls_with_client() @@ -110,15 +110,18 @@ class TlsFeedback(TlsLayer): # inline script hooks below. +tls_strategy = None -def start(context): + +def start(): + global tls_strategy if len(sys.argv) == 2: - context.tls_strategy = ProbabilisticStrategy(float(sys.argv[1])) + tls_strategy = ProbabilisticStrategy(float(sys.argv[1])) else: - context.tls_strategy = ConservativeStrategy() + tls_strategy = ConservativeStrategy() -def next_layer(context, next_layer): +def next_layer(next_layer): """ This hook does the actual magic - if the next layer is planned to be a TLS layer, we check if we want to enter pass-through mode instead. @@ -126,14 +129,13 @@ def next_layer(context, next_layer): if isinstance(next_layer, TlsLayer) and next_layer._client_tls: server_address = next_layer.server_conn.address - if context.tls_strategy.should_intercept(server_address): + if tls_strategy.should_intercept(server_address): # We try to intercept. # Monkey-Patch the layer to get feedback from the TLSLayer if interception worked. next_layer.__class__ = TlsFeedback - next_layer.script_context = context else: # We don't intercept - reply with a pass-through layer and add a "skipped" entry. - context.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info") - next_layer_replacement = RawTCPLayer(next_layer.ctx, logging=False) + mitmproxy.log("TLS passthrough for %s" % repr(next_layer.server_conn.address), "info") + next_layer_replacement = RawTCPLayer(next_layer.ctx, ignore=True) next_layer.reply.send(next_layer_replacement) - context.tls_strategy.record_skipped(server_address) + tls_strategy.record_skipped(server_address) diff --git a/examples/upsidedownternet.py b/examples/upsidedownternet.py index 9aac9f05c..fafdefcef 100644 --- a/examples/upsidedownternet.py +++ b/examples/upsidedownternet.py @@ -3,7 +3,7 @@ from PIL import Image from mitmproxy.models import decoded -def response(context, flow): +def response(flow): if flow.response.headers.get("content-type", "").startswith("image"): with decoded(flow.response): # automatically decode gzipped responses. try: diff --git a/test/mitmproxy/data/scripts/a.py b/test/mitmproxy/data/scripts/a.py index 33dbaa64c..ab0dbf96f 100644 --- a/test/mitmproxy/data/scripts/a.py +++ b/test/mitmproxy/data/scripts/a.py @@ -5,12 +5,12 @@ from a_helper import parser var = 0 -def start(ctx): +def start(): global var var = parser.parse_args(sys.argv[1:]).var -def here(ctx): +def here(): global var var += 1 return var diff --git a/test/mitmproxy/data/scripts/all.py b/test/mitmproxy/data/scripts/all.py index dad2aade7..17ffe33f0 100644 --- a/test/mitmproxy/data/scripts/all.py +++ b/test/mitmproxy/data/scripts/all.py @@ -1,36 +1,37 @@ +import mitmproxy log = [] -def clientconnect(ctx, cc): - ctx.log("XCLIENTCONNECT") +def clientconnect(cc): + mitmproxy.log("XCLIENTCONNECT") log.append("clientconnect") -def serverconnect(ctx, cc): - ctx.log("XSERVERCONNECT") +def serverconnect(cc): + mitmproxy.log("XSERVERCONNECT") log.append("serverconnect") -def request(ctx, f): - ctx.log("XREQUEST") +def request(f): + mitmproxy.log("XREQUEST") log.append("request") -def response(ctx, f): - ctx.log("XRESPONSE") +def response(f): + mitmproxy.log("XRESPONSE") log.append("response") -def responseheaders(ctx, f): - ctx.log("XRESPONSEHEADERS") +def responseheaders(f): + mitmproxy.log("XRESPONSEHEADERS") log.append("responseheaders") -def clientdisconnect(ctx, cc): - ctx.log("XCLIENTDISCONNECT") +def clientdisconnect(cc): + mitmproxy.log("XCLIENTDISCONNECT") log.append("clientdisconnect") -def error(ctx, cc): - ctx.log("XERROR") +def error(cc): + mitmproxy.log("XERROR") log.append("error") diff --git a/test/mitmproxy/data/scripts/concurrent_decorator.py b/test/mitmproxy/data/scripts/concurrent_decorator.py index e017f6056..162c00f4b 100644 --- a/test/mitmproxy/data/scripts/concurrent_decorator.py +++ b/test/mitmproxy/data/scripts/concurrent_decorator.py @@ -3,5 +3,5 @@ from mitmproxy.script import concurrent @concurrent -def request(context, flow): +def request(flow): time.sleep(0.1) diff --git a/test/mitmproxy/data/scripts/concurrent_decorator_err.py b/test/mitmproxy/data/scripts/concurrent_decorator_err.py index 349e5dd64..756869c8f 100644 --- a/test/mitmproxy/data/scripts/concurrent_decorator_err.py +++ b/test/mitmproxy/data/scripts/concurrent_decorator_err.py @@ -2,5 +2,5 @@ from mitmproxy.script import concurrent @concurrent -def start(context): +def start(): pass diff --git a/test/mitmproxy/data/scripts/duplicate_flow.py b/test/mitmproxy/data/scripts/duplicate_flow.py index e13af786d..a50d2cb51 100644 --- a/test/mitmproxy/data/scripts/duplicate_flow.py +++ b/test/mitmproxy/data/scripts/duplicate_flow.py @@ -1,4 +1,6 @@ +import mitmproxy -def request(ctx, f): - f = ctx.duplicate_flow(f) - ctx.replay_request(f) + +def request(f): + f = mitmproxy.master.duplicate_flow(f) + mitmproxy.master.replay_request(f, block=True, run_scripthooks=False) diff --git a/test/mitmproxy/data/scripts/reqerr.py b/test/mitmproxy/data/scripts/reqerr.py index e7c503a87..7b4193611 100644 --- a/test/mitmproxy/data/scripts/reqerr.py +++ b/test/mitmproxy/data/scripts/reqerr.py @@ -1,2 +1,2 @@ -def request(ctx, r): - raise ValueError +def request(r): + raise ValueError() diff --git a/test/mitmproxy/data/scripts/starterr.py b/test/mitmproxy/data/scripts/starterr.py index 82d773bd9..28ba2ff15 100644 --- a/test/mitmproxy/data/scripts/starterr.py +++ b/test/mitmproxy/data/scripts/starterr.py @@ -1,3 +1,3 @@ -def start(ctx): +def start(): raise ValueError() diff --git a/test/mitmproxy/data/scripts/stream_modify.py b/test/mitmproxy/data/scripts/stream_modify.py index 8221b0dd0..4fbf45c26 100644 --- a/test/mitmproxy/data/scripts/stream_modify.py +++ b/test/mitmproxy/data/scripts/stream_modify.py @@ -3,5 +3,5 @@ def modify(chunks): yield chunk.replace(b"foo", b"bar") -def responseheaders(context, flow): +def responseheaders(flow): flow.response.stream = modify diff --git a/test/mitmproxy/data/scripts/tcp_stream_modify.py b/test/mitmproxy/data/scripts/tcp_stream_modify.py index 0965beba9..2281e6e6d 100644 --- a/test/mitmproxy/data/scripts/tcp_stream_modify.py +++ b/test/mitmproxy/data/scripts/tcp_stream_modify.py @@ -1,4 +1,4 @@ -def tcp_message(ctx, flow): +def tcp_message(flow): message = flow.messages[-1] if not message.from_client: message.content = message.content.replace(b"foo", b"bar") diff --git a/test/mitmproxy/data/scripts/unloaderr.py b/test/mitmproxy/data/scripts/unloaderr.py index fba027344..6a48ab43e 100644 --- a/test/mitmproxy/data/scripts/unloaderr.py +++ b/test/mitmproxy/data/scripts/unloaderr.py @@ -1,2 +1,2 @@ -def done(ctx): +def done(): raise RuntimeError()