finish proxy.py split up
This commit is contained in:
parent
fc4fe83eaf
commit
5598a8de82
|
@ -17,12 +17,12 @@ def index():
|
|||
|
||||
@mapp.route("/cert/pem")
|
||||
def certs_pem():
|
||||
p = os.path.join(master().server.config.confdir, proxy.CONF_BASENAME + "-ca-cert.pem")
|
||||
p = os.path.join(master().server.config.confdir, proxy.config.CONF_BASENAME + "-ca-cert.pem")
|
||||
return flask.Response(open(p, "rb").read(), mimetype='application/x-x509-ca-cert')
|
||||
|
||||
|
||||
@mapp.route("/cert/p12")
|
||||
def certs_p12():
|
||||
p = os.path.join(master().server.config.confdir, proxy.CONF_BASENAME + "-ca-cert.p12")
|
||||
p = os.path.join(master().server.config.confdir, proxy.config.CONF_BASENAME + "-ca-cert.p12")
|
||||
return flask.Response(open(p, "rb").read(), mimetype='application/x-pkcs12')
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import proxy
|
||||
from . import proxy
|
||||
import re, filt
|
||||
import argparse
|
||||
|
||||
|
@ -387,4 +387,4 @@ def common_options(parser):
|
|||
help="Allow access to users specified in an Apache htpasswd file."
|
||||
)
|
||||
|
||||
proxy.ssl_option_group(parser)
|
||||
proxy.config.ssl_option_group(parser)
|
||||
|
|
|
@ -7,13 +7,15 @@ import hashlib, Cookie, cookielib, re, threading
|
|||
import os
|
||||
import flask
|
||||
import requests
|
||||
from . import controller, protocol
|
||||
from .protocol import http
|
||||
from .proxy.connection import ServerConnection
|
||||
from .proxy.primitives import ProxyError
|
||||
import tnetstring, filt, script
|
||||
from netlib import odict, wsgi
|
||||
import controller, version, protocol
|
||||
from netlib import odict, wsgi, tcp
|
||||
import netlib.http
|
||||
import version
|
||||
import app
|
||||
from .protocol import KILL
|
||||
from .protocol.http import HTTPResponse, CONTENT_MISSING
|
||||
from .proxy import RequestReplayThread
|
||||
|
||||
ODict = odict.ODict
|
||||
ODictCaseless = odict.ODictCaseless
|
||||
|
@ -564,7 +566,7 @@ class FlowMaster(controller.Master):
|
|||
rflow = self.server_playback.next_flow(flow)
|
||||
if not rflow:
|
||||
return None
|
||||
response = HTTPResponse._from_state(rflow.response._get_state())
|
||||
response = http.HTTPResponse._from_state(rflow.response._get_state())
|
||||
response.is_replay = True
|
||||
if self.refresh_server_playback:
|
||||
response.refresh()
|
||||
|
@ -641,7 +643,7 @@ class FlowMaster(controller.Master):
|
|||
"""
|
||||
if f.intercepting:
|
||||
return "Can't replay while intercepting..."
|
||||
if f.request.content == CONTENT_MISSING:
|
||||
if f.request.content == http.CONTENT_MISSING:
|
||||
return "Can't replay request with missing content..."
|
||||
if f.request:
|
||||
f.request.is_replay = True
|
||||
|
@ -692,7 +694,7 @@ class FlowMaster(controller.Master):
|
|||
err = app.serve(r, r.flow.client_conn.wfile, **{"mitmproxy.master": self})
|
||||
if err:
|
||||
self.add_event("Error in wsgi app. %s"%err, "error")
|
||||
r.reply(KILL)
|
||||
r.reply(protocol.KILL)
|
||||
return
|
||||
f = self.state.add_request(r)
|
||||
self.replacehooks.run(f)
|
||||
|
@ -784,3 +786,25 @@ class FilteredFlowWriter:
|
|||
d = f._get_state()
|
||||
tnetstring.dump(d, self.fo)
|
||||
|
||||
|
||||
class RequestReplayThread(threading.Thread):
|
||||
name="RequestReplayThread"
|
||||
|
||||
def __init__(self, config, flow, masterq):
|
||||
self.config, self.flow, self.channel = config, flow, controller.Channel(masterq)
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
r = self.flow.request
|
||||
server = ServerConnection(self.flow.server_conn.address(), None)
|
||||
server.connect()
|
||||
if self.flow.server_conn.ssl_established:
|
||||
server.establish_ssl(self.config.clientcerts,
|
||||
self.flow.server_conn.sni)
|
||||
server.send(r._assemble())
|
||||
self.flow.response = http.HTTPResponse.from_stream(server.rfile, r.method, body_size_limit=self.config.body_size_limit)
|
||||
self.channel.ask("response", self.flow.response)
|
||||
except (ProxyError, netlib.http.HttpError, tcp.NetLibError), v:
|
||||
self.flow.error = protocol.primitives.Error(str(v))
|
||||
self.channel.ask("error", self.flow.error)
|
|
@ -1,4 +1,4 @@
|
|||
from ..prxy.server import AddressPriority
|
||||
from libmproxy.proxy.primitives import AddressPriority
|
||||
|
||||
KILL = 0 # const for killed requests
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Cookie, urllib, urlparse, time, copy
|
||||
from email.utils import parsedate_tz, formatdate, mktime_tz
|
||||
from ..prxy.connection import ServerConnection
|
||||
from ..prxy.exception import ProxyError, ConnectionTypeChange
|
||||
from ..prxy.server import AddressPriority
|
||||
from libmproxy.proxy.primitives import AddressPriority
|
||||
from ..proxy.connection import ServerConnection
|
||||
from ..proxy.primitives import ProxyError, ConnectionTypeChange
|
||||
import netlib.utils
|
||||
from netlib import http, tcp, http_status
|
||||
from netlib.odict import ODict, ODictCaseless
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from .. import stateobject, utils, version
|
||||
from ..prxy.connection import ClientConnection, ServerConnection
|
||||
from ..proxy.connection import ClientConnection, ServerConnection
|
||||
import copy
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
import os
|
||||
from .. import utils, platform
|
||||
from netlib import http_auth, certutils
|
||||
|
||||
|
||||
TRANSPARENT_SSL_PORTS = [443, 8443]
|
||||
CONF_BASENAME = "mitmproxy"
|
||||
CONF_DIR = "~/.mitmproxy"
|
||||
|
||||
|
||||
class ProxyConfig:
|
||||
def __init__(self, confdir=CONF_DIR, clientcerts=None,
|
||||
no_upstream_cert=False, body_size_limit=None, reverse_proxy=None,
|
||||
forward_proxy=None, transparent_proxy=None, authenticator=None,
|
||||
ciphers=None, certs=None
|
||||
):
|
||||
self.ciphers = ciphers
|
||||
self.clientcerts = clientcerts
|
||||
self.no_upstream_cert = no_upstream_cert
|
||||
self.body_size_limit = body_size_limit
|
||||
self.reverse_proxy = reverse_proxy
|
||||
self.forward_proxy = forward_proxy
|
||||
self.transparent_proxy = transparent_proxy
|
||||
self.authenticator = authenticator
|
||||
self.confdir = os.path.expanduser(confdir)
|
||||
self.certstore = certutils.CertStore.from_store(self.confdir, CONF_BASENAME)
|
||||
|
||||
|
||||
def process_proxy_options(parser, options):
|
||||
body_size_limit = utils.parse_size(options.body_size_limit)
|
||||
if options.reverse_proxy and options.transparent_proxy:
|
||||
return parser.error("Can't set both reverse proxy and transparent proxy.")
|
||||
|
||||
if options.transparent_proxy:
|
||||
if not platform.resolver:
|
||||
return parser.error("Transparent mode not supported on this platform.")
|
||||
trans = dict(
|
||||
resolver=platform.resolver(),
|
||||
sslports=TRANSPARENT_SSL_PORTS
|
||||
)
|
||||
else:
|
||||
trans = None
|
||||
|
||||
if options.reverse_proxy:
|
||||
rp = utils.parse_proxy_spec(options.reverse_proxy)
|
||||
if not rp:
|
||||
return parser.error("Invalid reverse proxy specification: %s" % options.reverse_proxy)
|
||||
else:
|
||||
rp = None
|
||||
|
||||
if options.forward_proxy:
|
||||
fp = utils.parse_proxy_spec(options.forward_proxy)
|
||||
if not fp:
|
||||
return parser.error("Invalid forward proxy specification: %s" % options.forward_proxy)
|
||||
else:
|
||||
fp = None
|
||||
|
||||
if options.clientcerts:
|
||||
options.clientcerts = os.path.expanduser(options.clientcerts)
|
||||
if not os.path.exists(options.clientcerts) or not os.path.isdir(options.clientcerts):
|
||||
return parser.error(
|
||||
"Client certificate directory does not exist or is not a directory: %s" % options.clientcerts
|
||||
)
|
||||
|
||||
if (options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd):
|
||||
if options.auth_singleuser:
|
||||
if len(options.auth_singleuser.split(':')) != 2:
|
||||
return parser.error("Invalid single-user specification. Please use the format username:password")
|
||||
username, password = options.auth_singleuser.split(':')
|
||||
password_manager = http_auth.PassManSingleUser(username, password)
|
||||
elif options.auth_nonanonymous:
|
||||
password_manager = http_auth.PassManNonAnon()
|
||||
elif options.auth_htpasswd:
|
||||
try:
|
||||
password_manager = http_auth.PassManHtpasswd(options.auth_htpasswd)
|
||||
except ValueError, v:
|
||||
return parser.error(v.message)
|
||||
authenticator = http_auth.BasicProxyAuth(password_manager, "mitmproxy")
|
||||
else:
|
||||
authenticator = http_auth.NullProxyAuth(None)
|
||||
|
||||
certs = []
|
||||
for i in options.certs:
|
||||
parts = i.split("=", 1)
|
||||
if len(parts) == 1:
|
||||
parts = ["*", parts[0]]
|
||||
parts[1] = os.path.expanduser(parts[1])
|
||||
if not os.path.exists(parts[1]):
|
||||
parser.error("Certificate file does not exist: %s"%parts[1])
|
||||
certs.append(parts)
|
||||
|
||||
return ProxyConfig(
|
||||
clientcerts=options.clientcerts,
|
||||
body_size_limit=body_size_limit,
|
||||
no_upstream_cert=options.no_upstream_cert,
|
||||
reverse_proxy=rp,
|
||||
forward_proxy=fp,
|
||||
transparent_proxy=trans,
|
||||
authenticator=authenticator,
|
||||
ciphers=options.ciphers,
|
||||
certs = certs,
|
||||
)
|
||||
|
||||
|
||||
def ssl_option_group(parser):
|
||||
group = parser.add_argument_group("SSL")
|
||||
group.add_argument(
|
||||
"--cert", dest='certs', default=[], type=str,
|
||||
metavar = "SPEC", action="append",
|
||||
help='Add an SSL certificate. SPEC is of the form "[domain=]path". '\
|
||||
'The domain may include a wildcard, and is equal to "*" if not specified. '\
|
||||
'The file at path is a certificate in PEM format. If a private key is included in the PEM, '\
|
||||
'it is used, else the default key in the conf dir is used. Can be passed multiple times.'
|
||||
)
|
||||
group.add_argument(
|
||||
"--client-certs", action="store",
|
||||
type=str, dest="clientcerts", default=None,
|
||||
help="Client certificate directory."
|
||||
)
|
||||
group.add_argument(
|
||||
"--ciphers", action="store",
|
||||
type=str, dest="ciphers", default=None,
|
||||
help="SSL cipher specification."
|
||||
)
|
|
@ -1,9 +1,10 @@
|
|||
import copy
|
||||
import os
|
||||
from .. import stateobject, utils
|
||||
from .exception import ProxyError
|
||||
from .primitives import ProxyError
|
||||
from netlib import tcp, certutils
|
||||
|
||||
|
||||
class ClientConnection(tcp.BaseHandler, stateobject.SimpleStateObject):
|
||||
def __init__(self, client_connection, address, server):
|
||||
if client_connection: # Eventually, this object is restored from state. We don't have a connection then.
|
|
@ -0,0 +1,40 @@
|
|||
class ProxyError(Exception):
|
||||
def __init__(self, code, msg, headers=None):
|
||||
self.code, self.msg, self.headers = code, msg, headers
|
||||
|
||||
def __str__(self):
|
||||
return "ProxyError(%s, %s)" % (self.code, self.msg)
|
||||
|
||||
|
||||
class ConnectionTypeChange(Exception):
|
||||
"""
|
||||
Gets raised if the connection type has been changed (e.g. after HTTP/1.1 101 Switching Protocols).
|
||||
It's up to the raising ProtocolHandler to specify the new conntype before raising the exception.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ProxyServerError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class AddressPriority(object):
|
||||
"""
|
||||
Enum that signifies the priority of the given address when choosing the destination host.
|
||||
Higher is better (None < i)
|
||||
"""
|
||||
FORCE = 5
|
||||
"""forward mode"""
|
||||
MANUALLY_CHANGED = 4
|
||||
"""user changed the target address in the ui"""
|
||||
FROM_SETTINGS = 3
|
||||
"""reverse proxy mode"""
|
||||
FROM_CONNECTION = 2
|
||||
"""derived from transparent resolver"""
|
||||
FROM_PROTOCOL = 1
|
||||
"""derived from protocol (e.g. absolute-form http requests)"""
|
||||
|
||||
|
||||
class Log:
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
|
@ -1,73 +1,51 @@
|
|||
import os
|
||||
import socket
|
||||
import threading
|
||||
|
||||
from OpenSSL import SSL
|
||||
|
||||
from .prxy.connection import ClientConnection, ServerConnection
|
||||
from .prxy.exception import ProxyError, ConnectionTypeChange
|
||||
from .prxy.server import AddressPriority
|
||||
from netlib import tcp, http, certutils, http_auth
|
||||
import utils
|
||||
import version
|
||||
import platform
|
||||
import controller
|
||||
from .. import version, protocol
|
||||
from libmproxy.proxy.primitives import Log
|
||||
from .primitives import ProxyServerError
|
||||
from .connection import ClientConnection, ServerConnection
|
||||
from .primitives import ProxyError, ConnectionTypeChange, AddressPriority
|
||||
from netlib import tcp
|
||||
|
||||
|
||||
TRANSPARENT_SSL_PORTS = [443, 8443]
|
||||
CONF_BASENAME = "mitmproxy"
|
||||
CONF_DIR = "~/.mitmproxy"
|
||||
CA_CERT_NAME = "mitmproxy-ca.pem"
|
||||
class DummyServer:
|
||||
bound = False
|
||||
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
def start_slave(self, *args):
|
||||
pass
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
|
||||
class Log:
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
|
||||
|
||||
class ProxyConfig:
|
||||
def __init__(self, confdir=CONF_DIR, clientcerts=None,
|
||||
no_upstream_cert=False, body_size_limit=None, reverse_proxy=None,
|
||||
forward_proxy=None, transparent_proxy=None, authenticator=None,
|
||||
ciphers=None, certs=None
|
||||
):
|
||||
self.ciphers = ciphers
|
||||
self.clientcerts = clientcerts
|
||||
self.no_upstream_cert = no_upstream_cert
|
||||
self.body_size_limit = body_size_limit
|
||||
self.reverse_proxy = reverse_proxy
|
||||
self.forward_proxy = forward_proxy
|
||||
self.transparent_proxy = transparent_proxy
|
||||
self.authenticator = authenticator
|
||||
self.confdir = os.path.expanduser(confdir)
|
||||
self.certstore = certutils.CertStore.from_store(self.confdir, CONF_BASENAME)
|
||||
|
||||
|
||||
from . import protocol
|
||||
from .protocol.http import HTTPResponse
|
||||
|
||||
|
||||
class RequestReplayThread(threading.Thread):
|
||||
name="RequestReplayThread"
|
||||
|
||||
def __init__(self, config, flow, masterq):
|
||||
self.config, self.flow, self.channel = config, flow, controller.Channel(masterq)
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
class ProxyServer(tcp.TCPServer):
|
||||
allow_reuse_address = True
|
||||
bound = True
|
||||
def __init__(self, config, port, host='', server_version=version.NAMEVERSION):
|
||||
"""
|
||||
Raises ProxyServerError if there's a startup problem.
|
||||
"""
|
||||
self.config = config
|
||||
self.server_version = server_version
|
||||
try:
|
||||
r = self.flow.request
|
||||
server = ServerConnection(self.flow.server_conn.address(), None)
|
||||
server.connect()
|
||||
if self.flow.server_conn.ssl_established:
|
||||
server.establish_ssl(self.config.clientcerts,
|
||||
self.flow.server_conn.sni)
|
||||
server.send(r._assemble())
|
||||
self.flow.response = HTTPResponse.from_stream(server.rfile, r.method, body_size_limit=self.config.body_size_limit)
|
||||
self.channel.ask("response", self.flow.response)
|
||||
except (ProxyError, http.HttpError, tcp.NetLibError), v:
|
||||
self.flow.error = protocol.primitives.Error(str(v))
|
||||
self.channel.ask("error", self.flow.error)
|
||||
tcp.TCPServer.__init__(self, (host, port))
|
||||
except socket.error, v:
|
||||
raise ProxyServerError('Error starting proxy server: ' + v.strerror)
|
||||
self.channel = None
|
||||
|
||||
def start_slave(self, klass, channel):
|
||||
slave = klass(channel, self)
|
||||
slave.start()
|
||||
|
||||
def set_channel(self, channel):
|
||||
self.channel = channel
|
||||
|
||||
def handle_client_connection(self, conn, client_address):
|
||||
h = ConnectionHandler(self.config, conn, client_address, self, self.channel, self.server_version)
|
||||
h.handle()
|
||||
h.finish()
|
||||
|
||||
|
||||
class ConnectionHandler:
|
||||
|
@ -174,7 +152,7 @@ class ConnectionHandler:
|
|||
"""
|
||||
Sets a new server address with the given priority.
|
||||
Does not re-establish either connection or SSL handshake.
|
||||
@type priority: libmproxy.prxy.server.AddressPriority
|
||||
@type priority: libmproxy.proxy.primitives.AddressPriority
|
||||
"""
|
||||
address = tcp.Address.wrap(address)
|
||||
|
||||
|
@ -241,7 +219,7 @@ class ConnectionHandler:
|
|||
raise ProxyError(502, "SSL to Client already established.")
|
||||
cert, key = self.find_cert()
|
||||
self.client_conn.convert_to_ssl(
|
||||
cert, key,
|
||||
cert, key,
|
||||
handle_sni = self.handle_sni,
|
||||
cipher_list = self.config.ciphers
|
||||
)
|
||||
|
@ -306,148 +284,4 @@ class ConnectionHandler:
|
|||
# An unhandled exception in this method will core dump PyOpenSSL, so
|
||||
# make dang sure it doesn't happen.
|
||||
except Exception, e: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class ProxyServerError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ProxyServer(tcp.TCPServer):
|
||||
allow_reuse_address = True
|
||||
bound = True
|
||||
def __init__(self, config, port, host='', server_version=version.NAMEVERSION):
|
||||
"""
|
||||
Raises ProxyServerError if there's a startup problem.
|
||||
"""
|
||||
self.config = config
|
||||
self.server_version = server_version
|
||||
try:
|
||||
tcp.TCPServer.__init__(self, (host, port))
|
||||
except socket.error, v:
|
||||
raise ProxyServerError('Error starting proxy server: ' + v.strerror)
|
||||
self.channel = None
|
||||
|
||||
def start_slave(self, klass, channel):
|
||||
slave = klass(channel, self)
|
||||
slave.start()
|
||||
|
||||
def set_channel(self, channel):
|
||||
self.channel = channel
|
||||
|
||||
def handle_client_connection(self, conn, client_address):
|
||||
h = ConnectionHandler(self.config, conn, client_address, self, self.channel, self.server_version)
|
||||
h.handle()
|
||||
h.finish()
|
||||
|
||||
|
||||
class DummyServer:
|
||||
bound = False
|
||||
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
def start_slave(self, *args):
|
||||
pass
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
|
||||
# Command-line utils
|
||||
def ssl_option_group(parser):
|
||||
group = parser.add_argument_group("SSL")
|
||||
group.add_argument(
|
||||
"--cert", dest='certs', default=[], type=str,
|
||||
metavar = "SPEC", action="append",
|
||||
help='Add an SSL certificate. SPEC is of the form "[domain=]path". '\
|
||||
'The domain may include a wildcard, and is equal to "*" if not specified. '\
|
||||
'The file at path is a certificate in PEM format. If a private key is included in the PEM, '\
|
||||
'it is used, else the default key in the conf dir is used. Can be passed multiple times.'
|
||||
)
|
||||
group.add_argument(
|
||||
"--client-certs", action="store",
|
||||
type=str, dest="clientcerts", default=None,
|
||||
help="Client certificate directory."
|
||||
)
|
||||
group.add_argument(
|
||||
"--ciphers", action="store",
|
||||
type=str, dest="ciphers", default=None,
|
||||
help="SSL cipher specification."
|
||||
)
|
||||
|
||||
|
||||
def process_proxy_options(parser, options):
|
||||
body_size_limit = utils.parse_size(options.body_size_limit)
|
||||
if options.reverse_proxy and options.transparent_proxy:
|
||||
return parser.error("Can't set both reverse proxy and transparent proxy.")
|
||||
|
||||
if options.transparent_proxy:
|
||||
if not platform.resolver:
|
||||
return parser.error("Transparent mode not supported on this platform.")
|
||||
trans = dict(
|
||||
resolver=platform.resolver(),
|
||||
sslports=TRANSPARENT_SSL_PORTS
|
||||
)
|
||||
else:
|
||||
trans = None
|
||||
|
||||
if options.reverse_proxy:
|
||||
rp = utils.parse_proxy_spec(options.reverse_proxy)
|
||||
if not rp:
|
||||
return parser.error("Invalid reverse proxy specification: %s" % options.reverse_proxy)
|
||||
else:
|
||||
rp = None
|
||||
|
||||
if options.forward_proxy:
|
||||
fp = utils.parse_proxy_spec(options.forward_proxy)
|
||||
if not fp:
|
||||
return parser.error("Invalid forward proxy specification: %s" % options.forward_proxy)
|
||||
else:
|
||||
fp = None
|
||||
|
||||
if options.clientcerts:
|
||||
options.clientcerts = os.path.expanduser(options.clientcerts)
|
||||
if not os.path.exists(options.clientcerts) or not os.path.isdir(options.clientcerts):
|
||||
return parser.error(
|
||||
"Client certificate directory does not exist or is not a directory: %s" % options.clientcerts
|
||||
)
|
||||
|
||||
if (options.auth_nonanonymous or options.auth_singleuser or options.auth_htpasswd):
|
||||
if options.auth_singleuser:
|
||||
if len(options.auth_singleuser.split(':')) != 2:
|
||||
return parser.error("Invalid single-user specification. Please use the format username:password")
|
||||
username, password = options.auth_singleuser.split(':')
|
||||
password_manager = http_auth.PassManSingleUser(username, password)
|
||||
elif options.auth_nonanonymous:
|
||||
password_manager = http_auth.PassManNonAnon()
|
||||
elif options.auth_htpasswd:
|
||||
try:
|
||||
password_manager = http_auth.PassManHtpasswd(options.auth_htpasswd)
|
||||
except ValueError, v:
|
||||
return parser.error(v.message)
|
||||
authenticator = http_auth.BasicProxyAuth(password_manager, "mitmproxy")
|
||||
else:
|
||||
authenticator = http_auth.NullProxyAuth(None)
|
||||
|
||||
certs = []
|
||||
for i in options.certs:
|
||||
parts = i.split("=", 1)
|
||||
if len(parts) == 1:
|
||||
parts = ["*", parts[0]]
|
||||
parts[1] = os.path.expanduser(parts[1])
|
||||
if not os.path.exists(parts[1]):
|
||||
parser.error("Certificate file does not exist: %s"%parts[1])
|
||||
certs.append(parts)
|
||||
|
||||
return ProxyConfig(
|
||||
clientcerts=options.clientcerts,
|
||||
body_size_limit=body_size_limit,
|
||||
no_upstream_cert=options.no_upstream_cert,
|
||||
reverse_proxy=rp,
|
||||
forward_proxy=fp,
|
||||
transparent_proxy=trans,
|
||||
authenticator=authenticator,
|
||||
ciphers=options.ciphers,
|
||||
certs = certs,
|
||||
)
|
||||
pass
|
|
@ -1,14 +0,0 @@
|
|||
class ProxyError(Exception):
|
||||
def __init__(self, code, msg, headers=None):
|
||||
self.code, self.msg, self.headers = code, msg, headers
|
||||
|
||||
def __str__(self):
|
||||
return "ProxyError(%s, %s)" % (self.code, self.msg)
|
||||
|
||||
|
||||
class ConnectionTypeChange(Exception):
|
||||
"""
|
||||
Gets raised if the connection type has been changed (e.g. after HTTP/1.1 101 Switching Protocols).
|
||||
It's up to the raising ProtocolHandler to specify the new conntype before raising the exception.
|
||||
"""
|
||||
pass
|
|
@ -1,18 +0,0 @@
|
|||
__author__ = 'user'
|
||||
|
||||
|
||||
class AddressPriority(object):
|
||||
"""
|
||||
Enum that signifies the priority of the given address when choosing the destination host.
|
||||
Higher is better (None < i)
|
||||
"""
|
||||
FORCE = 5
|
||||
"""forward mode"""
|
||||
MANUALLY_CHANGED = 4
|
||||
"""user changed the target address in the ui"""
|
||||
FROM_SETTINGS = 3
|
||||
"""reverse proxy mode"""
|
||||
FROM_CONNECTION = 2
|
||||
"""derived from transparent resolver"""
|
||||
FROM_PROTOCOL = 1
|
||||
"""derived from protocol (e.g. absolute-form http requests)"""
|
11
mitmdump
11
mitmdump
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
import sys, signal
|
||||
from libmproxy import proxy, dump, cmdline
|
||||
from libmproxy.proxy.config import process_proxy_options
|
||||
from libmproxy.proxy.primitives import ProxyServerError
|
||||
from libmproxy.proxy.server import DummyServer, ProxyServer
|
||||
import libmproxy.version, netlib.version
|
||||
import argparse
|
||||
|
||||
|
@ -25,13 +28,13 @@ if __name__ == '__main__':
|
|||
if options.quiet:
|
||||
options.verbose = 0
|
||||
|
||||
proxyconfig = proxy.process_proxy_options(parser, options)
|
||||
proxyconfig = process_proxy_options(parser, options)
|
||||
if options.no_server:
|
||||
server = proxy.DummyServer(proxyconfig)
|
||||
server = DummyServer(proxyconfig)
|
||||
else:
|
||||
try:
|
||||
server = proxy.ProxyServer(proxyconfig, options.port, options.addr)
|
||||
except proxy.ProxyServerError, v:
|
||||
server = ProxyServer(proxyconfig, options.port, options.addr)
|
||||
except ProxyServerError, v:
|
||||
print >> sys.stderr, "mitmdump:", v.args[0]
|
||||
sys.exit(1)
|
||||
|
||||
|
|
11
mitmproxy
11
mitmproxy
|
@ -1,6 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
import sys, argparse, os
|
||||
from libmproxy import proxy, console, cmdline
|
||||
from libmproxy.proxy.config import process_proxy_options
|
||||
from libmproxy.proxy.primitives import ProxyServerError
|
||||
from libmproxy.proxy.server import DummyServer, ProxyServer
|
||||
import libmproxy.version, netlib.version
|
||||
from libmproxy.console import palettes
|
||||
|
||||
|
@ -33,14 +36,14 @@ if __name__ == '__main__':
|
|||
)
|
||||
options = parser.parse_args()
|
||||
|
||||
config = proxy.process_proxy_options(parser, options)
|
||||
config = process_proxy_options(parser, options)
|
||||
|
||||
if options.no_server:
|
||||
server = proxy.DummyServer(config)
|
||||
server = DummyServer(config)
|
||||
else:
|
||||
try:
|
||||
server = proxy.ProxyServer(config, options.port, options.addr)
|
||||
except proxy.ProxyServerError, v:
|
||||
server = ProxyServer(config, options.port, options.addr)
|
||||
except ProxyServerError, v:
|
||||
print >> sys.stderr, "mitmproxy:", v.args[0]
|
||||
sys.exit(1)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import os
|
||||
from cStringIO import StringIO
|
||||
from libmproxy import dump, flow, proxy, prxy
|
||||
from libmproxy import dump, flow, proxy
|
||||
from libmproxy.proxy.primitives import Log
|
||||
import tutils
|
||||
import mock
|
||||
|
||||
|
@ -21,13 +22,13 @@ def test_strfuncs():
|
|||
class TestDumpMaster:
|
||||
def _cycle(self, m, content):
|
||||
req = tutils.treq(content=content)
|
||||
l = proxy.Log("connect")
|
||||
l = Log("connect")
|
||||
l.reply = mock.MagicMock()
|
||||
m.handle_log(l)
|
||||
cc = req.flow.client_conn
|
||||
cc.reply = mock.MagicMock()
|
||||
m.handle_clientconnect(cc)
|
||||
sc = prxy.connection.ServerConnection((req.get_host(), req.get_port()), None)
|
||||
sc = proxy.connection.ServerConnection((req.get_host(), req.get_port()), None)
|
||||
sc.reply = mock.MagicMock()
|
||||
m.handle_serverconnection(sc)
|
||||
m.handle_request(req)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Queue, time, os.path
|
||||
from cStringIO import StringIO
|
||||
import email.utils
|
||||
from libmproxy import filt, protocol, controller, utils, tnetstring, proxy, flow
|
||||
from libmproxy import filt, protocol, controller, utils, tnetstring, flow
|
||||
from libmproxy.protocol.primitives import Error, Flow
|
||||
from libmproxy.protocol.http import decoded
|
||||
from libmproxy.prxy.connection import ClientConnection, ServerConnection
|
||||
from libmproxy.protocol.http import decoded, CONTENT_MISSING
|
||||
from libmproxy.proxy.connection import ClientConnection, ServerConnection
|
||||
from netlib import tcp
|
||||
import tutils
|
||||
|
||||
|
@ -566,7 +566,7 @@ class TestFlowMaster:
|
|||
s = flow.State()
|
||||
fm = flow.FlowMaster(None, s)
|
||||
f = tutils.tflow_full()
|
||||
f.request.content = flow.CONTENT_MISSING
|
||||
f.request.content = CONTENT_MISSING
|
||||
assert "missing" in fm.replay_request(f)
|
||||
|
||||
f.intercepting = True
|
||||
|
@ -796,7 +796,7 @@ class TestRequest:
|
|||
assert r._assemble()
|
||||
assert r.size() == len(r._assemble())
|
||||
|
||||
r.content = flow.CONTENT_MISSING
|
||||
r.content = CONTENT_MISSING
|
||||
tutils.raises("Cannot assemble flow with CONTENT_MISSING", r._assemble)
|
||||
|
||||
def test_get_url(self):
|
||||
|
@ -1004,7 +1004,7 @@ class TestResponse:
|
|||
assert resp._assemble()
|
||||
assert resp.size() == len(resp._assemble())
|
||||
|
||||
resp.content = flow.CONTENT_MISSING
|
||||
resp.content = CONTENT_MISSING
|
||||
tutils.raises("Cannot assemble flow with CONTENT_MISSING", resp._assemble)
|
||||
|
||||
def test_refresh(self):
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
from libmproxy import proxy # FIXME: Remove
|
||||
from libmproxy.protocol.http import *
|
||||
from libmproxy.protocol import KILL
|
||||
from cStringIO import StringIO
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import argparse
|
||||
from libmproxy import proxy, flow, cmdline
|
||||
from libmproxy.prxy.connection import ServerConnection
|
||||
from libmproxy.prxy.exception import ProxyError
|
||||
from libmproxy import cmdline
|
||||
from libmproxy.proxy.config import process_proxy_options
|
||||
from libmproxy.proxy.connection import ServerConnection
|
||||
from libmproxy.proxy.primitives import ProxyError
|
||||
from libmproxy.proxy.server import DummyServer, ProxyServer
|
||||
import tutils
|
||||
from libpathod import test
|
||||
from netlib import http, tcp
|
||||
|
@ -58,7 +60,7 @@ class TestProcessProxyOptions:
|
|||
cmdline.common_options(parser)
|
||||
opts = parser.parse_args(args=args)
|
||||
m = MockParser()
|
||||
return m, proxy.process_proxy_options(m, opts)
|
||||
return m, process_proxy_options(m, opts)
|
||||
|
||||
def assert_err(self, err, *args):
|
||||
m, p = self.p(*args)
|
||||
|
@ -117,12 +119,12 @@ class TestProxyServer:
|
|||
parser = argparse.ArgumentParser()
|
||||
cmdline.common_options(parser)
|
||||
opts = parser.parse_args(args=[])
|
||||
tutils.raises("error starting proxy server", proxy.ProxyServer, opts, 1)
|
||||
tutils.raises("error starting proxy server", ProxyServer, opts, 1)
|
||||
|
||||
|
||||
class TestDummyServer:
|
||||
def test_simple(self):
|
||||
d = proxy.DummyServer(None)
|
||||
d = DummyServer(None)
|
||||
d.start_slave()
|
||||
d.shutdown()
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ import mock
|
|||
from netlib import tcp, http_auth, http
|
||||
from libpathod import pathoc, pathod
|
||||
import tutils, tservers
|
||||
from libmproxy import flow, proxy
|
||||
from libmproxy.protocol import KILL
|
||||
from libmproxy.protocol.http import CONTENT_MISSING
|
||||
|
||||
"""
|
||||
Note that the choice of response code in these tests matters more than you
|
||||
|
@ -381,7 +381,7 @@ class TestTransparentResolveError(tservers.TransparentProxTest):
|
|||
class MasterIncomplete(tservers.TestMaster):
|
||||
def handle_request(self, m):
|
||||
resp = tutils.tresp()
|
||||
resp.content = flow.CONTENT_MISSING
|
||||
resp.content = CONTENT_MISSING
|
||||
m.reply(resp)
|
||||
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@ import os.path
|
|||
import threading, Queue
|
||||
import shutil, tempfile
|
||||
import flask
|
||||
from libmproxy.proxy.config import ProxyConfig
|
||||
from libmproxy.proxy.server import ProxyServer
|
||||
import libpathod.test, libpathod.pathoc
|
||||
from libmproxy import proxy, flow, controller
|
||||
from libmproxy import flow, controller
|
||||
from libmproxy.cmdline import APP_HOST, APP_PORT
|
||||
import tutils
|
||||
|
||||
|
@ -24,7 +26,7 @@ def errapp(environ, start_response):
|
|||
|
||||
class TestMaster(flow.FlowMaster):
|
||||
def __init__(self, config):
|
||||
s = proxy.ProxyServer(config, 0)
|
||||
s = ProxyServer(config, 0)
|
||||
state = flow.State()
|
||||
flow.FlowMaster.__init__(self, s, state)
|
||||
self.apps.add(testapp, "testapp", 80)
|
||||
|
@ -84,7 +86,7 @@ class ProxTestBase(object):
|
|||
cls.server2 = libpathod.test.Daemon(ssl=cls.ssl, ssloptions=cls.ssloptions)
|
||||
pconf = cls.get_proxy_config()
|
||||
cls.confdir = os.path.join(tempfile.gettempdir(), "mitmproxy")
|
||||
config = proxy.ProxyConfig(
|
||||
config = ProxyConfig(
|
||||
no_upstream_cert = cls.no_upstream_cert,
|
||||
confdir = cls.confdir,
|
||||
authenticator = cls.authenticator,
|
||||
|
@ -256,7 +258,7 @@ class ChainProxTest(ProxTestBase):
|
|||
Chain n instances of mitmproxy in a row - because we can.
|
||||
"""
|
||||
n = 2
|
||||
chain_config = [lambda: proxy.ProxyConfig(
|
||||
chain_config = [lambda: ProxyConfig(
|
||||
)] * n
|
||||
@classmethod
|
||||
def setupAll(cls):
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import os, shutil, tempfile
|
||||
from contextlib import contextmanager
|
||||
from libmproxy import flow, utils, controller, proxy
|
||||
from libmproxy import flow, utils, controller
|
||||
from libmproxy.protocol import http
|
||||
from libmproxy.prxy.connection import ClientConnection, ServerConnection
|
||||
from libmproxy.proxy.connection import ClientConnection, ServerConnection
|
||||
import mock_urwid
|
||||
from libmproxy.console.flowview import FlowView
|
||||
from libmproxy.console import ConsoleState
|
||||
|
|
Loading…
Reference in New Issue