diff --git a/burpui/api/settings.py b/burpui/api/settings.py index a3ead473..8e81371b 100644 --- a/burpui/api/settings.py +++ b/burpui/api/settings.py @@ -12,6 +12,7 @@ from burpui.api import api from flask.ext.restful import reqparse, abort, Resource from flask.ext.login import current_user, login_required from flask import jsonify, flash, request, redirect, url_for +from urllib import unquote @api.resource('/api/server-config', @@ -163,6 +164,10 @@ class ServerSettings(Resource): api.bui.acl.is_admin(current_user.name)): abort(403, message='Sorry, you don\'t have rights to access the setting panel') + try: + conf = unquote(conf) + except: + pass r = api.bui.cli.read_conf_srv(conf, server) return jsonify(results=r, boolean=api.bui.cli.get_parser_attr('boolean_srv', server), @@ -189,6 +194,10 @@ class ClientSettings(Resource): api.bui.acl.is_admin(current_user.name)): abort(403, message='Sorry, you don\'t have rights to access the setting panel') + try: + conf = unquote(conf) + except: + pass r = api.bui.cli.read_conf_cli(client, conf, server) return jsonify(results=r, boolean=api.bui.cli.get_parser_attr('boolean_cli', server), diff --git a/burpui/misc/backend/burp1.py b/burpui/misc/backend/burp1.py index 35232fef..ed86b430 100644 --- a/burpui/misc/backend/burp1.py +++ b/burpui/misc/backend/burp1.py @@ -23,6 +23,7 @@ import tempfile import codecs from pipes import quote +from urllib import unquote from burpui.misc.utils import human_readable as _hr, BUIlogging, BUIcompress from burpui.misc.backend.interface import BUIbackend, BUIserverException @@ -931,11 +932,19 @@ class Burp(BUIbackend, BUIlogging): def store_conf_cli(self, data, client=None, conf=None, agent=None): if not self.parser: return [] + try: + conf = unquote(conf) + except: + pass return self.parser.store_client_conf(data, client, conf) def store_conf_srv(self, data, conf=None, agent=None): if not self.parser: return [] + try: + conf = unquote(conf) + except: + pass return self.parser.store_conf(data, conf) def expand_path(self, path=None, client=None, agent=None): diff --git a/burpui/misc/parser/burp1.py b/burpui/misc/parser/burp1.py index cf222980..e9b2323b 100644 --- a/burpui/misc/parser/burp1.py +++ b/burpui/misc/parser/burp1.py @@ -542,7 +542,7 @@ class Parser(BUIparser, BUIlogging): for l in fi: if re.match('^\s*#', l): continue - r = re.search('\s*(\S+)\s*=?\s*(.*)$', l) + r = re.search('\s*([^=\s]+)\s*=?\s*(.*)$', l) if r: key = r.group(1) val = r.group(2) @@ -599,7 +599,7 @@ class Parser(BUIparser, BUIlogging): if not re.search('\?|\*|\[.*\]', pattern): return [pattern] else: - return [x for x in glob(pattern) if os.path.isfile(x)] + return [x for x in glob(pattern) if os.path.isfile(x) and not x.endswith('~')] def remove_client(self, client=None): if not client: @@ -681,6 +681,15 @@ class Parser(BUIparser, BUIlogging): return res + def store_client_conf(self, data, client=None, conf=None): + if conf and not conf.startswith('/'): + conf = os.path.join(self.clientconfdir, conf) + if not conf and not client: + return [[2, 'Sorry, no client defined']] + elif client and not conf: + conf = os.path.join(self.clientconfdir, client) + return self.store_conf(data, conf) + def store_conf(self, data, conf=None): mconf = None if not conf: @@ -691,6 +700,7 @@ class Parser(BUIparser, BUIlogging): mconf = os.path.join(self.root, mconf) if not mconf: return [[1, 'Sorry, no configuration file defined']] + dirname = os.path.dirname(mconf) if not os.path.exists(dirname): try: @@ -698,8 +708,12 @@ class Parser(BUIparser, BUIlogging): except OSError as e: return [[1, str(e)]] orig = [] - ref = '{}.bui.init.back'.format(mconf) - bak = '{}.bak'.format(mconf) + if self.clientconfdir in dirname: + ref = '{}.bui.init.back~'.format(mconf) + bak = '{}.bak~'.format(mconf) + else: + ref = '{}.bui.init.back'.format(mconf) + bak = '{}.bak'.format(mconf) if not os.path.isfile(ref): try: shutil.copy(mconf, ref) diff --git a/burpui/misc/parser/interface.py b/burpui/misc/parser/interface.py index cbe11874..5d41d9d6 100644 --- a/burpui/misc/parser/interface.py +++ b/burpui/misc/parser/interface.py @@ -9,7 +9,10 @@ class BUIparser(object): def read_server_conf(self): raise NotImplementedError("Sorry, the current Parser does not implement this method!") - def store_conf(self, data): + def store_client_conf(self, data, client=None, conf=None): + raise NotImplementedError("Sorry, the current Parser does not implement this method!") + + def store_conf(self, data, conf=None): raise NotImplementedError("Sorry, the current Parser does not implement this method!") def get_priv_attr(self, key): diff --git a/burpui/routes.py b/burpui/routes.py index 629be885..a9dc3eb7 100644 --- a/burpui/routes.py +++ b/burpui/routes.py @@ -3,6 +3,7 @@ import math from flask import request, render_template, jsonify, redirect, url_for, abort, flash, Blueprint from flask.ext.login import login_user, login_required, logout_user, current_user +from urllib import quote from burpui.forms import LoginForm from burpui.misc.utils import human_readable as _hr @@ -59,13 +60,16 @@ def settings(server=None, conf=None): # Only the admin can edit the configuration if view.bui.acl and not view.bui.acl.is_admin(current_user.name): abort(403) + if not conf: + try: + conf = quote(request.args.get('conf'), safe='') + except: + pass + if not server: + server = request.args.get('server') if request.method == 'POST': noti = view.bui.cli.store_conf_srv(request.form, conf, server) return jsonify(notif=noti) - if not conf: - conf = request.args.get('conf') - if not server: - server = request.args.get('server') return render_template('settings.html', settings=True, server=server, conf=conf) @@ -80,15 +84,18 @@ def cli_settings(server=None, client=None, conf=None): # Only the admin can edit the configuration if view.bui.acl and not view.bui.acl.is_admin(current_user.name): abort(403) - if request.method == 'POST': - noti = view.bui.cli.store_conf_cli(request.form, server) - return jsonify(notif=noti) if not conf: - conf = request.args.get('conf') + try: + conf = quote(request.args.get('conf'), safe='') + except: + pass if not client: client = request.args.get('client') if not server: server = request.args.get('server') + if request.method == 'POST': + noti = view.bui.cli.store_conf_cli(request.form, client, conf, server) + return jsonify(notif=noti) return render_template('settings.html', settings=True, client=client, server=server, conf=conf)