diff --git a/libmproxy/app.py b/libmproxy/app.py index cb250939..9ad0fa46 100644 --- a/libmproxy/app.py +++ b/libmproxy/app.py @@ -12,10 +12,13 @@ mapp = flask.Flask(__name__) mapp.debug = True mapp.secret_key = os.urandom(16).encode("hex") -auth_token = os.urandom(16).encode("hex") -xsrf_token = os.urandom(16).encode("hex") -print "Auth token: ",auth_token +def auth_token(): + if not mapp.config.get("auth_token",False): + mapp.config["auth_token"] = os.urandom(16).encode("hex") + print "Auth token:", mapp.config["auth_token"] + return mapp.config["auth_token"] +xsrf_token = os.urandom(16).encode("hex") @mapp.before_request def auth(): @@ -29,12 +32,21 @@ def auth(): return else: token = request.args.get("auth",False) + if auth_token() == "NO_AUTH": + token = "NO_AUTH" if token: - if hashlib.sha1(auth_token).hexdigest() == hashlib.sha1(token).hexdigest(): + if hashlib.sha1(auth_token()).hexdigest() == hashlib.sha1(token).hexdigest(): session['auth'] = True return raise Unauthorized() +def require_write_permission(f): + def wrap(*args, **kwargs): + if not mapp.config["readonly"]: + return f(*args, **kwargs) + raise Unauthorized() + return wrap + @mapp.route("/") def index(): @@ -60,7 +72,8 @@ def config(): m = mapp.config["PMASTER"] return jsonify( proxy=m.server.server_address, - token=xsrf_token + token=xsrf_token, + readonly=mapp.config["readonly"] ) @@ -78,7 +91,8 @@ def _flow(flowid=None): @mapp.route("/api/flows") def flowlist(): flows = list(f._get_state() for f in _flow()) - for flow in flows: + for i, flow in enumerate(flows): + flow["id"] = i if flow["request"]: del flow["request"]["content"] if flow["response"]: @@ -89,6 +103,7 @@ def flowlist(): @mapp.route("/api/flows/") def flow(flowid): flow = _flow(flowid)._get_state() + flow["id"] = flowid if flow["request"]: del flow["request"]["content"] if flow["response"]: @@ -153,6 +168,7 @@ class FilesystemApi: raise InternalServerError() @staticmethod + @require_write_permission def POST(path, exists, isfile, isdir): if exists: raise Conflict() @@ -164,6 +180,7 @@ class FilesystemApi: return jsonify(success=True), 201 @staticmethod + @require_write_permission def PUT(path, exists, isfile, isdir): if not exists: raise Conflict() @@ -172,6 +189,7 @@ class FilesystemApi: return jsonify(success=True) @staticmethod + @require_write_permission def DELETE(path, exists, isfile, isdir): if not exists: raise NotFound() diff --git a/libmproxy/cmdline.py b/libmproxy/cmdline.py index bf6bbb69..cac5d007 100644 --- a/libmproxy/cmdline.py +++ b/libmproxy/cmdline.py @@ -221,10 +221,15 @@ def add_common_arguments(parser): entry for the app domain is not present.""" ) parser.add_argument( - "--readonly", - action="store_true", dest="readonly", + "--app-readonly", + action="store_true", dest="app_readonly", help="Don't allow web clients to modify files on disk (e.g. report scripts)" ) + parser.add_argument( + "--app-auth", + action="store", dest="app_auth", default="NO_AUTH", + help="Authentication string for the API." + ) group = parser.add_argument_group("Client Replay") diff --git a/libmproxy/flow.py b/libmproxy/flow.py index da946b0b..59924e0f 100644 --- a/libmproxy/flow.py +++ b/libmproxy/flow.py @@ -1368,6 +1368,8 @@ class FlowMaster(controller.Master): app.mapp.config["PMASTER"] = self def start_app(self, domain, ip): + app.mapp.config["auth_token"] = self.o.app_auth + app.mapp.config["readonly"] = self.o.app_readonly self.server.apps.add( app.mapp, domain, diff --git a/libmproxy/gui/mitmproxy/views/ReportEditor.js b/libmproxy/gui/mitmproxy/views/ReportEditor.js index 686571f0..a2f6ac83 100644 --- a/libmproxy/gui/mitmproxy/views/ReportEditor.js +++ b/libmproxy/gui/mitmproxy/views/ReportEditor.js @@ -8,9 +8,10 @@ define(["lodash", "dojo/request", "codemirror", "../report/context", - "../util/requestAuthenticator" + "../config", + "../util/requestAuthenticator" ], function(_, declare, Deferred, _ReactiveTemplatedWidget, template, domConstruct, query, request, - CodeMirror, reportContext) { + CodeMirror, reportContext, config) { var done = new Deferred(); done.resolve(); @@ -119,7 +120,7 @@ define(["lodash", } }, isFileReadOnly: function() { - if (this.readonly) + if (config.get("readonly")) return true; if (this.filename && this.filename[0] === "=") return true;