From ba42984b593246b0105a077311e16a2ca71f79eb Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Tue, 10 Feb 2015 15:24:21 -0300 Subject: added support for creating new requests. still wip (not working for https) --- libmproxy/console/common.py | 11 +++++++++++ libmproxy/console/flowlist.py | 29 +++++++++++++++++++++++++++++ libmproxy/console/flowview.py | 14 ++------------ libmproxy/flow.py | 9 +++++++++ 4 files changed, 51 insertions(+), 12 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/console/common.py b/libmproxy/console/common.py index e4a4acba..a2cfd57b 100644 --- a/libmproxy/console/common.py +++ b/libmproxy/console/common.py @@ -17,6 +17,17 @@ VIEW_FLOW = 1 VIEW_FLOW_REQUEST = 0 VIEW_FLOW_RESPONSE = 1 +METHOD_OPTIONS = [ + ("get", "g"), + ("post", "p"), + ("put", "u"), + ("head", "h"), + ("trace", "t"), + ("delete", "d"), + ("options", "o"), + ("edit raw", "e"), +] + def highlight_key(s, k): l = [] diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index c5cef061..8dfaba95 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -1,5 +1,6 @@ from __future__ import absolute_import import urwid +from netlib import http from . import common def _mkhelp(): @@ -16,6 +17,7 @@ def _mkhelp(): ("g", "copy flow to clipboard"), ("l", "set limit filter pattern"), ("L", "load saved flows"), + ("n", "creates a new request"), ("r", "replay request"), ("V", "revert changes to request"), ("w", "save flows "), @@ -245,6 +247,31 @@ class FlowListBox(urwid.ListBox): self.master = master urwid.ListBox.__init__(self, master.flow_list_walker) + def get_method_raw(self, k): + if k: + self.get_url(k) + + def get_method(self, k): + if k == "e": + self.master.prompt("Method:", "", self.get_method_raw) + else: + method = "" + for i in common.METHOD_OPTIONS: + if i[1] == k: + method = i[0].upper() + self.get_url(method) + + def get_url(self,method): + self.master.prompt("Url:", "http://www.example.com/", self.new_request, method) + + def new_request(self, url, method): + try: + scheme, host, port, path = http.parse_url(url) + f = self.master.add_request(method, scheme, host, port, path) + self.master.view_flow(f) + except ValueError: + self.master.statusbar.message("Invalid Url") + def keypress(self, size, key): key = common.shortcuts(key) if key == "A": @@ -262,6 +289,8 @@ class FlowListBox(urwid.ListBox): self.master.state.last_saveload, self.master.load_flows_callback ) + elif key == "n": + self.master.prompt_onekey("Method", common.METHOD_OPTIONS, self.get_method) elif key == "F": self.master.toggle_follow_flows() elif key == "W": diff --git a/libmproxy/console/flowview.py b/libmproxy/console/flowview.py index d5d41f7b..5c91512c 100644 --- a/libmproxy/console/flowview.py +++ b/libmproxy/console/flowview.py @@ -109,16 +109,6 @@ cache = CallbackCache() class FlowView(common.WWrap): REQ = 0 RESP = 1 - method_options = [ - ("get", "g"), - ("post", "p"), - ("put", "u"), - ("head", "h"), - ("trace", "t"), - ("delete", "d"), - ("options", "o"), - ("edit raw", "e"), - ] highlight_color = "focusfield" @@ -504,7 +494,7 @@ class FlowView(common.WWrap): if m == "e": self.master.prompt_edit("Method", self.flow.request.method, self.set_method_raw) else: - for i in self.method_options: + for i in common.METHOD_OPTIONS: if i[1] == m: self.flow.request.method = i[0].upper() self.master.refresh_flow(self.flow) @@ -599,7 +589,7 @@ class FlowView(common.WWrap): elif part == "u" and self.state.view_flow_mode == common.VIEW_FLOW_REQUEST: self.master.prompt_edit("URL", message.url, self.set_url) elif part == "m" and self.state.view_flow_mode == common.VIEW_FLOW_REQUEST: - self.master.prompt_onekey("Method", self.method_options, self.edit_method) + self.master.prompt_onekey("Method", common.METHOD_OPTIONS, self.edit_method) elif part == "c" and self.state.view_flow_mode == common.VIEW_FLOW_RESPONSE: self.master.prompt_edit("Code", str(message.code), self.set_resp_code) elif part == "m" and self.state.view_flow_mode == common.VIEW_FLOW_RESPONSE: diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 49ec5a0b..d96b9b8c 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -763,6 +763,15 @@ class FlowMaster(controller.Master): def duplicate_flow(self, f): return self.load_flow(f.copy()) + def add_request(self, method, scheme, host, port, path): + f = http.HTTPFlow(None,None); + headers = ODictCaseless() + + req = http.HTTPRequest("relative", method, scheme, host, port, path, (1, 1), headers, None, + None, None, None) + f.request = req + return self.load_flow(f) + def load_flow(self, f): """ Loads a flow, and returns a new flow object. -- cgit v1.2.3 From 80da33b2d322d23f8958d6e6c81cad6ae9c5349b Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Tue, 10 Feb 2015 15:45:11 -0300 Subject: request is absolute --- libmproxy/flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libmproxy') diff --git a/libmproxy/flow.py b/libmproxy/flow.py index d96b9b8c..e9d90916 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -767,7 +767,7 @@ class FlowMaster(controller.Master): f = http.HTTPFlow(None,None); headers = ODictCaseless() - req = http.HTTPRequest("relative", method, scheme, host, port, path, (1, 1), headers, None, + req = http.HTTPRequest("absolute", method, scheme, host, port, path, (1, 1), headers, None, None, None, None) f.request = req return self.load_flow(f) -- cgit v1.2.3 From 1df78f75c5ceb368ca9ba9d1b01e17af21cab892 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Tue, 10 Feb 2015 17:18:23 -0300 Subject: set sni to None when no server_conn is None --- libmproxy/protocol/http.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index 2f858a7c..79a4bf74 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -1457,9 +1457,11 @@ class RequestReplayThread(threading.Thread): server = ServerConnection(server_address) server.connect() if r.scheme == "https": - server.establish_ssl(self.config.clientcerts, sni=self.flow.server_conn.sni) + sni = None + if self.flow.server_conn: + sni = self.flow.server_conn.sni + server.establish_ssl(self.config.clientcerts, sni=sni) r.form_out = "relative" - server.send(r.assemble()) self.flow.server_conn = server self.flow.response = HTTPResponse.from_stream(server.rfile, r.method, -- cgit v1.2.3 From 493cecfaf27f7680c8acaaa88a467fc016a00bf8 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Wed, 11 Feb 2015 16:05:49 -0300 Subject: renamed add_request to create_request and added a tiny docstring --- libmproxy/console/flowlist.py | 2 +- libmproxy/flow.py | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index 8dfaba95..7d511682 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -267,7 +267,7 @@ class FlowListBox(urwid.ListBox): def new_request(self, url, method): try: scheme, host, port, path = http.parse_url(url) - f = self.master.add_request(method, scheme, host, port, path) + f = self.master.create_request(method, scheme, host, port, path) self.master.view_flow(f) except ValueError: self.master.statusbar.message("Invalid Url") diff --git a/libmproxy/flow.py b/libmproxy/flow.py index e9d90916..42fc36cc 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -763,7 +763,13 @@ class FlowMaster(controller.Master): def duplicate_flow(self, f): return self.load_flow(f.copy()) - def add_request(self, method, scheme, host, port, path): + def create_request(self, method, scheme, host, port, path): + """ + Creates a new request from params and add it to flow list. + created request is empty (except for method and url) but is able + to be replayed + + """ f = http.HTTPFlow(None,None); headers = ODictCaseless() -- cgit v1.2.3 From 27a1947599f33e7c57c185231f7e623a8b2d4dee Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Wed, 11 Feb 2015 22:03:57 -0300 Subject: missing str in http.parse_url --- libmproxy/console/flowlist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libmproxy') diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index 7d511682..92d58d11 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -266,7 +266,7 @@ class FlowListBox(urwid.ListBox): def new_request(self, url, method): try: - scheme, host, port, path = http.parse_url(url) + scheme, host, port, path = http.parse_url(str(url)) f = self.master.create_request(method, scheme, host, port, path) self.master.view_flow(f) except ValueError: -- cgit v1.2.3 From 16653cc62be4109cd465594ca2f5226d954027f2 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Thu, 12 Feb 2015 00:31:05 -0300 Subject: fixed typos --- libmproxy/console/flowlist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index 92d58d11..cd866819 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -17,7 +17,7 @@ def _mkhelp(): ("g", "copy flow to clipboard"), ("l", "set limit filter pattern"), ("L", "load saved flows"), - ("n", "creates a new request"), + ("n", "create a new request"), ("r", "replay request"), ("V", "revert changes to request"), ("w", "save flows "), @@ -262,7 +262,7 @@ class FlowListBox(urwid.ListBox): self.get_url(method) def get_url(self,method): - self.master.prompt("Url:", "http://www.example.com/", self.new_request, method) + self.master.prompt("URL:", "http://www.example.com/", self.new_request, method) def new_request(self, url, method): try: -- cgit v1.2.3 From 58091b704111b3192693f1af763888c50c68a481 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Thu, 12 Feb 2015 01:33:35 -0300 Subject: removed useless try except --- libmproxy/console/flowlist.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/console/flowlist.py b/libmproxy/console/flowlist.py index cd866819..9e7c6d69 100644 --- a/libmproxy/console/flowlist.py +++ b/libmproxy/console/flowlist.py @@ -265,12 +265,13 @@ class FlowListBox(urwid.ListBox): self.master.prompt("URL:", "http://www.example.com/", self.new_request, method) def new_request(self, url, method): - try: - scheme, host, port, path = http.parse_url(str(url)) - f = self.master.create_request(method, scheme, host, port, path) - self.master.view_flow(f) - except ValueError: + parts = http.parse_url(str(url)) + if not parts: self.master.statusbar.message("Invalid Url") + return + scheme, host, port, path = parts + f = self.master.create_request(method, scheme, host, port, path) + self.master.view_flow(f) def keypress(self, size, key): key = common.shortcuts(key) -- cgit v1.2.3 From fbba6bfe06c79c44ef1947baeb3344dccc8aa483 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Thu, 12 Feb 2015 01:42:48 -0300 Subject: added ClientConnection and ServerConnection to new request --- libmproxy/flow.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 42fc36cc..1870761f 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -8,12 +8,13 @@ import Cookie import cookielib import os import re -from netlib import odict, wsgi +from netlib import odict, wsgi, tcp import netlib.http from . import controller, protocol, tnetstring, filt, script, version from .onboarding import app from .protocol import http, handle from .proxy.config import HostMatcher +from .proxy.connection import ClientConnection, ServerConnection import urlparse ODict = odict.ODict @@ -768,9 +769,19 @@ class FlowMaster(controller.Master): Creates a new request from params and add it to flow list. created request is empty (except for method and url) but is able to be replayed - """ - f = http.HTTPFlow(None,None); + c = ClientConnection.from_state(dict( + address=dict(address=(host, port), use_ipv6=False), + clientcert=None + )) + + s = ServerConnection.from_state(dict( + address=dict(address=(host, port), use_ipv6=False), + state=[], + source_address=None, #source_address=dict(address=(host, port), use_ipv6=False), + cert=None + )) + f = http.HTTPFlow(c,s); headers = ODictCaseless() req = http.HTTPRequest("absolute", method, scheme, host, port, path, (1, 1), headers, None, -- cgit v1.2.3 From 71a58289e27bed18ca40bd9e62d67cff10467dc0 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Thu, 12 Feb 2015 01:52:13 -0300 Subject: less is more --- libmproxy/flow.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 1870761f..3c5ac1fe 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -766,9 +766,7 @@ class FlowMaster(controller.Master): def create_request(self, method, scheme, host, port, path): """ - Creates a new request from params and add it to flow list. - created request is empty (except for method and url) but is able - to be replayed + this method creates a new artificial and minimalist request also adds it to flowlist """ c = ClientConnection.from_state(dict( address=dict(address=(host, port), use_ipv6=False), -- cgit v1.2.3 From 010b921a93b2c7e3d6b26ca0db4538a56d7c8fb0 Mon Sep 17 00:00:00 2001 From: Marcelo Glezer Date: Thu, 12 Feb 2015 13:41:58 -0300 Subject: added sni and ssl_established=true in ServerConnection. removed check for None value of server_conn in http.py --- libmproxy/flow.py | 4 +++- libmproxy/protocol/http.py | 5 +---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'libmproxy') diff --git a/libmproxy/flow.py b/libmproxy/flow.py index 3c5ac1fe..14497964 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -777,7 +777,9 @@ class FlowMaster(controller.Master): address=dict(address=(host, port), use_ipv6=False), state=[], source_address=None, #source_address=dict(address=(host, port), use_ipv6=False), - cert=None + cert=None, + sni=host, + ssl_established=True )) f = http.HTTPFlow(c,s); headers = ODictCaseless() diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index 79a4bf74..046d0b42 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -1457,10 +1457,7 @@ class RequestReplayThread(threading.Thread): server = ServerConnection(server_address) server.connect() if r.scheme == "https": - sni = None - if self.flow.server_conn: - sni = self.flow.server_conn.sni - server.establish_ssl(self.config.clientcerts, sni=sni) + server.establish_ssl(self.config.clientcerts, sni=self.flow.server_conn.sni) r.form_out = "relative" server.send(r.assemble()) self.flow.server_conn = server -- cgit v1.2.3