Certificates are now generated in a temporary per-session directory.
This means that certificates don't accumulate in the conf directory, users don't have to clear certificates if the CA is regenerated, and the user can specify a custom CA without invalid certificates being loaded inadvertently.
This commit is contained in:
parent
c2ae8285f4
commit
7ddba22f51
|
@ -215,7 +215,7 @@ class State:
|
|||
Add an error response to the state. Returns the matching flow, or
|
||||
None if there isn't one.
|
||||
"""
|
||||
f = self.flow_map.get(err.flow.request)
|
||||
f = self.flow_map.get(err.request) if err.request else None
|
||||
if not f:
|
||||
return None
|
||||
f.error = err
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
Development started from Neil Schemenauer's munchy.py
|
||||
"""
|
||||
import sys, os, time, string, socket, urlparse, re, select, copy, base64
|
||||
import shutil, tempfile
|
||||
import optparse, SocketServer, ssl
|
||||
import utils, controller
|
||||
|
||||
|
@ -21,11 +22,11 @@ class ProxyError(Exception):
|
|||
|
||||
|
||||
class Config:
|
||||
def __init__(self, certfile = None, certpath = None, ciphers = None, cacert = None):
|
||||
def __init__(self, certfile = None, ciphers = None, cacert = None):
|
||||
self.certfile = certfile
|
||||
self.certpath = certpath
|
||||
self.ciphers = ciphers
|
||||
self.cacert = cacert
|
||||
self.certdir = None
|
||||
|
||||
|
||||
def read_chunked(fp):
|
||||
|
@ -369,8 +370,8 @@ class ClientConnect(controller.Msg):
|
|||
|
||||
|
||||
class Error(controller.Msg):
|
||||
def __init__(self, flow, msg, timestamp=None):
|
||||
self.flow, self.msg = flow, msg
|
||||
def __init__(self, request, msg, timestamp=None):
|
||||
self.request, self.msg = request, msg
|
||||
self.timestamp = timestamp or time.time()
|
||||
controller.Msg.__init__(self)
|
||||
|
||||
|
@ -509,7 +510,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
|
|||
self.finish()
|
||||
|
||||
def handle_request(self, cc):
|
||||
server = None
|
||||
server, request = None, None
|
||||
try:
|
||||
request = self.read_request(cc)
|
||||
if request is None:
|
||||
|
@ -538,7 +539,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
|
|||
except IOError:
|
||||
pass
|
||||
except ProxyError, e:
|
||||
err = Error(cc, e.msg)
|
||||
err = Error(request, e.msg)
|
||||
err.send(self.mqueue)
|
||||
cc.close = True
|
||||
self.send_error(e.code, e.msg)
|
||||
|
@ -549,7 +550,7 @@ class ProxyHandler(SocketServer.StreamRequestHandler):
|
|||
if self.config.certfile:
|
||||
return self.config.certfile
|
||||
else:
|
||||
ret = utils.dummy_cert(self.config.certpath, self.config.cacert, host)
|
||||
ret = utils.dummy_cert(self.config.certdir, self.config.cacert, host)
|
||||
if not ret:
|
||||
raise ProxyError(400, "mitmproxy: Unable to generate dummy cert.")
|
||||
return ret
|
||||
|
@ -667,6 +668,8 @@ class ProxyServer(ServerBase):
|
|||
self.config, self.port, self.address = config, port, address
|
||||
ServerBase.__init__(self, (address, port), ProxyHandler)
|
||||
self.masterq = None
|
||||
self.certdir = tempfile.mkdtemp(prefix="mitmproxy")
|
||||
config.certdir = self.certdir
|
||||
|
||||
def set_mqueue(self, q):
|
||||
self.masterq = q
|
||||
|
@ -675,6 +678,7 @@ class ProxyServer(ServerBase):
|
|||
self.RequestHandlerClass(self.config, request, client_address, self, self.masterq)
|
||||
|
||||
def shutdown(self):
|
||||
shutil.rmtree(self.certdir)
|
||||
ServerBase.shutdown(self)
|
||||
|
||||
|
||||
|
@ -691,11 +695,6 @@ def certificate_option_group(parser):
|
|||
type = "str", dest="cacert", default="~/.mitmproxy/ca.pem",
|
||||
help = "SSL CA certificate file. Generated if it doesn't exist."
|
||||
)
|
||||
group.add_option(
|
||||
"--certpath", action="store",
|
||||
type = "str", dest="certpath", default="~/.mitmproxy/",
|
||||
help = "SSL certificate store path."
|
||||
)
|
||||
group.add_option(
|
||||
"--ciphers", action="store",
|
||||
type = "str", dest="ciphers", default=None,
|
||||
|
@ -713,21 +712,11 @@ def process_certificate_option_group(parser, options):
|
|||
if options.cacert:
|
||||
options.cacert = os.path.expanduser(options.cacert)
|
||||
if not os.path.exists(options.cacert):
|
||||
dummy_ca(options.cacert)
|
||||
if options.certpath:
|
||||
options.certpath = os.path.expanduser(options.certpath)
|
||||
elif options.cacert:
|
||||
options.certpath = os.path.dirname(options.cacert)
|
||||
|
||||
utils.dummy_ca(options.cacert)
|
||||
if getattr(options, "cache", None) is not None:
|
||||
options.cache = os.path.expanduser(options.cache)
|
||||
|
||||
return Config(
|
||||
certfile = options.cert,
|
||||
certpath = options.certpath,
|
||||
cacert = options.cacert,
|
||||
ciphers = options.ciphers
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
|
10
mitmdump
10
mitmdump
|
@ -54,16 +54,8 @@ if __name__ == '__main__':
|
|||
if options.quiet:
|
||||
options.verbose = 0
|
||||
|
||||
proxy.process_certificate_option_group(parser, options)
|
||||
|
||||
config = proxy.Config(
|
||||
certfile = options.cert,
|
||||
certpath = options.certpath,
|
||||
cacert = options.cacert,
|
||||
ciphers = options.ciphers
|
||||
)
|
||||
config = proxy.process_certificate_option_group(parser, options)
|
||||
server = proxy.ProxyServer(config, options.port)
|
||||
|
||||
dumpopts = dump.Options(
|
||||
verbosity = options.verbose,
|
||||
wfile = options.wfile,
|
||||
|
|
|
@ -56,17 +56,11 @@ if __name__ == '__main__':
|
|||
if options.quiet:
|
||||
options.verbose = 0
|
||||
|
||||
proxy.process_certificate_option_group(parser, options)
|
||||
|
||||
if options.cache is not None:
|
||||
options.cache = os.path.expanduser(options.cache)
|
||||
|
||||
config = proxy.Config(
|
||||
certfile = options.cert,
|
||||
certpath = options.certpath,
|
||||
cacert = options.cacert,
|
||||
ciphers = options.ciphers
|
||||
)
|
||||
config = proxy.process_certificate_option_group(parser, options)
|
||||
server = proxy.ProxyServer(config, options.port)
|
||||
m = playback.PlaybackMaster(server, options)
|
||||
m.run()
|
||||
|
|
10
mitmproxy
10
mitmproxy
|
@ -85,22 +85,16 @@ if __name__ == '__main__':
|
|||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
proxy.process_certificate_option_group(parser, options)
|
||||
|
||||
if options.cache is not None:
|
||||
options.cache = os.path.expanduser(options.cache)
|
||||
|
||||
config = proxy.Config(
|
||||
certfile = options.cert,
|
||||
certpath = options.certpath,
|
||||
cacert = options.cacert,
|
||||
ciphers = options.ciphers
|
||||
)
|
||||
if options.cache is not None:
|
||||
utils.mkdir_p(options.cache)
|
||||
if os.path.exists(options.cache + "/index.txt"):
|
||||
print >> sys.stderr, "ERROR: data already recorded in %s"%options.cache
|
||||
sys.exit(1)
|
||||
|
||||
config = proxy.process_certificate_option_group(parser, options)
|
||||
server = proxy.ProxyServer(config, options.port, options.addr)
|
||||
m = console.ConsoleMaster(server, options)
|
||||
|
||||
|
|
|
@ -61,14 +61,7 @@ if __name__ == '__main__':
|
|||
if options.quiet:
|
||||
options.verbose = 0
|
||||
|
||||
proxy.process_certificate_option_group(parser, options)
|
||||
|
||||
config = proxy.Config(
|
||||
certfile = options.cert,
|
||||
certpath = options.certpath,
|
||||
cacert = options.cacert,
|
||||
ciphers = options.ciphers
|
||||
)
|
||||
config = proxy.process_certificate_option_group(parser, options)
|
||||
server = proxy.ProxyServer(config, options.port)
|
||||
utils.mkdir_p(options.cache)
|
||||
if os.path.exists(options.cache + "/index.txt"):
|
||||
|
|
|
@ -47,12 +47,12 @@ class uFlow(libpry.AutoTree):
|
|||
assert f == flow.Flow.from_state(state)
|
||||
|
||||
f.response = None
|
||||
f.error = proxy.Error(f, "error")
|
||||
f.error = proxy.Error(f.request, "error")
|
||||
state = f.get_state()
|
||||
assert f == flow.Flow.from_state(state)
|
||||
|
||||
f2 = utils.tflow()
|
||||
f2.error = proxy.Error(f, "e2")
|
||||
f2.error = proxy.Error(f.request, "e2")
|
||||
assert not f == f2
|
||||
f.load_state(f2.get_state())
|
||||
assert f == f2
|
||||
|
@ -143,10 +143,10 @@ class uState(libpry.AutoTree):
|
|||
c = flow.State()
|
||||
req = utils.treq()
|
||||
f = c.add_request(req)
|
||||
e = proxy.Error(f, "message")
|
||||
e = proxy.Error(f.request, "message")
|
||||
assert c.add_error(e)
|
||||
|
||||
e = proxy.Error(utils.tflow(), "message")
|
||||
e = proxy.Error(utils.tflow().request, "message")
|
||||
assert not c.add_error(e)
|
||||
|
||||
def test_view(self):
|
||||
|
@ -190,7 +190,7 @@ class uState(libpry.AutoTree):
|
|||
def _add_error(self, state):
|
||||
req = utils.treq()
|
||||
f = state.add_request(req)
|
||||
f.error = proxy.Error(f, "msg")
|
||||
f.error = proxy.Error(f.request, "msg")
|
||||
|
||||
def test_kill_flow(self):
|
||||
c = flow.State()
|
||||
|
@ -269,7 +269,7 @@ class uFlowMaster(libpry.AutoTree):
|
|||
dc = proxy.ClientDisconnect(req.client_conn)
|
||||
fm.handle_clientdisconnect(dc)
|
||||
|
||||
err = proxy.Error(f, "msg")
|
||||
err = proxy.Error(f.request, "msg")
|
||||
fm.handle_error(err)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue