mirror of
https://github.com/ziirish/burp-ui.git
synced 2026-05-15 14:16:08 -06:00
Merge remote-tracking branch 'origin/master' into 212-last-backup-status-must-be-shown-in-client-view
This commit is contained in:
commit
bda360435c
23 changed files with 214 additions and 67 deletions
|
|
@ -116,7 +116,7 @@ class Api(ApiPlus):
|
|||
def decorator(func):
|
||||
@wraps(func)
|
||||
def decorated(resource, *args, **kwargs):
|
||||
if not hasattr(current_user, 'acl') or \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin():
|
||||
resource.abort(code, message)
|
||||
return func(resource, *args, **kwargs)
|
||||
|
|
@ -129,10 +129,9 @@ class Api(ApiPlus):
|
|||
def decorated(resource, *args, **kwargs):
|
||||
if key not in kwargs: # pragma: no cover
|
||||
resource.abort(500, "key '{}' not found".format(key))
|
||||
if (kwargs[key] != current_user.name and
|
||||
hasattr(current_user, 'acl') and
|
||||
not current_user.acl.is_admin()) or \
|
||||
not hasattr(current_user, 'acl'):
|
||||
if kwargs[key] != current_user.name and \
|
||||
not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin():
|
||||
resource.abort(code, message)
|
||||
return func(resource, *args, **kwargs)
|
||||
return decorated
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ class AuthUsers(Resource):
|
|||
args = self.parser_mod.parse_args()
|
||||
is_admin = True
|
||||
|
||||
if hasattr(current_user, 'acl'):
|
||||
if not current_user.is_anonymous:
|
||||
is_admin = current_user.acl.is_admin()
|
||||
|
||||
if not is_admin and not args['old_password']:
|
||||
|
|
|
|||
|
|
@ -308,7 +308,7 @@ class AsyncRestore(Resource):
|
|||
if not files or not name or not backup:
|
||||
self.abort(400, 'missing arguments')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(
|
||||
|
|
@ -686,7 +686,7 @@ class AsyncClientTreeAll(Resource):
|
|||
)
|
||||
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'Sorry, you are not allowed to view this client')
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class ServerBackup(Resource):
|
|||
if not name:
|
||||
self.abort(400, 'Missing options')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You are not allowed to access this client')
|
||||
|
|
@ -98,7 +98,7 @@ class ServerBackup(Resource):
|
|||
if not name:
|
||||
self.abort(400, 'Missing options')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You are not allowed to cancel a backup for this client')
|
||||
|
|
@ -134,7 +134,7 @@ class ServerBackup(Resource):
|
|||
if not name:
|
||||
self.abort(400, 'Missing options')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ class ClientTree(Resource):
|
|||
paths_loaded = []
|
||||
to_select_list = []
|
||||
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'Sorry, you are not allowed to view this client')
|
||||
|
|
@ -420,7 +420,7 @@ class ClientTreeAll(Resource):
|
|||
'Sorry, the requested backend does not support this method'
|
||||
)
|
||||
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'Sorry, you are not allowed to view this client')
|
||||
|
|
@ -787,7 +787,7 @@ class ClientReport(Resource):
|
|||
err = [[1, 'No client defined']]
|
||||
self.abort(400, err)
|
||||
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You don\'t have rights to view this client report')
|
||||
|
|
@ -852,7 +852,7 @@ class ClientReport(Resource):
|
|||
err = [[1, 'No client defined']]
|
||||
self.abort(400, err)
|
||||
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You don\'t have rights on this client')
|
||||
|
|
@ -948,7 +948,7 @@ class ClientStats(Resource):
|
|||
"""
|
||||
server = server or self.parser.parse_args()['serverName']
|
||||
try:
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'Sorry, you cannot access this client')
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class RunningClients(Resource):
|
|||
"""
|
||||
server = server or self.parser.parse_args()['serverName']
|
||||
if client:
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(client, server):
|
||||
running = []
|
||||
|
|
@ -86,7 +86,7 @@ class RunningClients(Resource):
|
|||
|
||||
running = bui.client.is_one_backup_running(server)
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
if isinstance(running, dict):
|
||||
new = {}
|
||||
for serv in bui.client.servers:
|
||||
|
|
@ -159,7 +159,7 @@ class RunningBackup(Resource):
|
|||
def _is_one_backup_running(self, res, server):
|
||||
"""Check if a backup is running"""
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
if isinstance(res, dict):
|
||||
new = {}
|
||||
for serv in bui.client.servers:
|
||||
|
|
@ -299,7 +299,7 @@ class ClientsReport(Resource):
|
|||
|
||||
def _check_acl(self, server):
|
||||
# Manage ACL
|
||||
if (not bui.standalone and hasattr(current_user, 'acl') and
|
||||
if (not bui.standalone and not current_user.is_anonymous and
|
||||
(not current_user.acl.is_admin() and
|
||||
not current_user.acl.is_server_allowed(server))):
|
||||
self.abort(403, 'Sorry, you don\'t have any rights on this server')
|
||||
|
|
@ -380,14 +380,14 @@ class ClientsReport(Resource):
|
|||
clients = bui.client.get_all_clients(agent=server)
|
||||
except BUIserverException as e:
|
||||
self.abort(500, str(e))
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
clients = [x for x in clients if current_user.acl.is_client_allowed(x['name'], server)]
|
||||
return bui.client.get_clients_report(clients, server)
|
||||
if bui.standalone:
|
||||
ret = res
|
||||
else:
|
||||
ret = res.get(server, {})
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
ret['backups'] = [x for x in ret.get('backups', []) if current_user.acl.is_client_allowed(x.get('name'), server)]
|
||||
ret['clients'] = [x for x in ret.get('clients', []) if current_user.acl.is_client_allowed(x.get('name'), server)]
|
||||
return ret
|
||||
|
|
@ -469,13 +469,12 @@ class ClientsStats(Resource):
|
|||
|
||||
server = server or self.parser.parse_args()['serverName']
|
||||
try:
|
||||
if (not bui.standalone and
|
||||
hasattr(current_user, 'acl') and
|
||||
if (not bui.standalone and not current_user.is_anonymous and
|
||||
(not current_user.acl.is_admin() and
|
||||
not current_user.acl.is_server_allowed(server))):
|
||||
self.abort(403, 'Sorry, you don\'t have any rights on this server')
|
||||
jso = bui.client.get_all_clients(agent=server)
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
jso = [x for x in jso if current_user.acl.is_client_allowed(x['name'], server)]
|
||||
except BUIserverException as e:
|
||||
self.abort(500, str(e))
|
||||
|
|
@ -550,12 +549,10 @@ class AllClients(Resource):
|
|||
"""
|
||||
ret = []
|
||||
is_admin = True
|
||||
has_acl = hasattr(current_user, 'acl')
|
||||
args = self.parser.parse_args()
|
||||
server = server or args['serverName']
|
||||
|
||||
if has_acl:
|
||||
is_admin = current_user.acl.is_admin()
|
||||
is_admin = current_user.is_anonymous or current_user.acl.is_admin()
|
||||
|
||||
user = (args.get('user', current_user.name) or current_user.name) if \
|
||||
is_admin \
|
||||
|
|
@ -565,7 +562,7 @@ class AllClients(Resource):
|
|||
if user != current_user.name:
|
||||
is_admin = False
|
||||
|
||||
if (server and has_acl and
|
||||
if (server and
|
||||
not is_admin and
|
||||
not current_user.acl.is_server_allowed(server)):
|
||||
self.abort(403, "You are not allowed to view this server infos")
|
||||
|
|
@ -575,7 +572,7 @@ class AllClients(Resource):
|
|||
clients = [x['name'] for x in bui.client.get_all_clients(agent=server)]
|
||||
except BUIserverException:
|
||||
clients = []
|
||||
if hasattr(current_user, 'acl') and not is_admin:
|
||||
if not is_admin:
|
||||
# use the bui.acl module since we impersonalized the user
|
||||
ret = [{'name': x, 'agent': server} for x in clients if bui.acl.is_client_allowed(user, x, server)]
|
||||
else:
|
||||
|
|
@ -587,7 +584,7 @@ class AllClients(Resource):
|
|||
clients = [x['name'] for x in bui.client.get_all_clients()]
|
||||
except BUIserverException:
|
||||
clients = []
|
||||
if has_acl and not is_admin:
|
||||
if not is_admin:
|
||||
ret = [{'name': x} for x in clients if bui.acl.is_client_allowed(user, x)]
|
||||
else:
|
||||
ret = [{'name': x} for x in clients]
|
||||
|
|
@ -600,7 +597,7 @@ class AllClients(Resource):
|
|||
clients_cache[serv] = clients
|
||||
except BUIserverException:
|
||||
clients = []
|
||||
if has_acl and not is_admin:
|
||||
if not is_admin:
|
||||
for serv in bui.client.servers:
|
||||
grants[serv] = [x for x in clients_cache.get(serv, []) if bui.acl.is_client_allowed(user, x, serv)]
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ class Counters(Resource):
|
|||
if not client:
|
||||
self.abort(400, 'No client name provided')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(client, server):
|
||||
self.abort(403, "Not allowed to view '{}' counters".format(client))
|
||||
|
|
@ -208,7 +208,7 @@ class Live(Resource):
|
|||
server = server or args['serverName']
|
||||
res = []
|
||||
is_admin = True
|
||||
has_acl = hasattr(current_user, 'acl')
|
||||
has_acl = not current_user.is_anonymous
|
||||
|
||||
if has_acl:
|
||||
is_admin = current_user.acl.is_admin()
|
||||
|
|
@ -523,7 +523,7 @@ class History(Resource):
|
|||
client = client or args['clientName']
|
||||
server = server or args['serverName']
|
||||
is_admin = True
|
||||
has_acl = hasattr(current_user, 'acl')
|
||||
has_acl = not current_user.is_anonymous
|
||||
|
||||
if has_acl:
|
||||
is_admin = current_user.acl.is_admin()
|
||||
|
|
@ -547,7 +547,7 @@ class History(Resource):
|
|||
'start': None,
|
||||
'end': None
|
||||
}
|
||||
has_acl = hasattr(current_user, 'acl')
|
||||
has_acl = not current_user.is_anonymous
|
||||
|
||||
if has_acl:
|
||||
is_admin = current_user.acl.is_admin()
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class Restore(Resource):
|
|||
if not l or not name or not backup:
|
||||
self.abort(400, 'missing arguments')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You are not allowed to perform a restoration for this client')
|
||||
|
|
@ -296,7 +296,7 @@ class ServerRestore(Resource):
|
|||
if not name:
|
||||
self.abort(400, 'Missing options')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You are not allowed to edit a restoration for this client')
|
||||
|
|
@ -330,7 +330,7 @@ class ServerRestore(Resource):
|
|||
if not name:
|
||||
self.abort(400, 'Missing options')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server):
|
||||
self.abort(403, 'You are not allowed to cancel a restoration for this client')
|
||||
|
|
@ -418,7 +418,7 @@ class DoServerRestore(Resource):
|
|||
if not files_list or not name or not backup:
|
||||
self.abort(400, 'Missing options')
|
||||
# Manage ACL
|
||||
if hasattr(current_user, 'acl') and \
|
||||
if not current_user.is_anonymous and \
|
||||
not current_user.acl.is_admin() and \
|
||||
not current_user.acl.is_client_allowed(name, server) and \
|
||||
not current_user.acl.is_client_allowed(to, server):
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class ServersStats(Resource):
|
|||
if bui.standalone:
|
||||
return r
|
||||
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
check = True
|
||||
|
||||
for serv in bui.client.servers:
|
||||
|
|
@ -170,7 +170,7 @@ class ServersReport(Resource):
|
|||
"""
|
||||
r = {}
|
||||
check = False
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
check = True
|
||||
|
||||
backups = []
|
||||
|
|
@ -189,7 +189,7 @@ class ServersReport(Resource):
|
|||
if check and not current_user.acl.is_server_allowed(serv):
|
||||
continue
|
||||
clients = bui.client.get_all_clients(agent=serv)
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if check:
|
||||
clients = [x for x in clients if current_user.acl.is_client_allowed(x['name'], serv)]
|
||||
|
||||
j = bui.client.get_clients_report(clients, serv)
|
||||
|
|
|
|||
|
|
@ -390,6 +390,7 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
|
|||
from .sessions import session_manager
|
||||
from .ext.cache import cache
|
||||
from .ext.i18n import babel, get_locale
|
||||
from .misc.auth.handler import BUIanon
|
||||
|
||||
logger = logging.getLogger('burp-ui')
|
||||
|
||||
|
|
@ -690,6 +691,7 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
|
|||
|
||||
# And the login_manager
|
||||
app.login_manager = LoginManager()
|
||||
app.login_manager.anonymous_user = BUIanon
|
||||
app.login_manager.login_view = 'view.login'
|
||||
app.login_manager.login_message_category = 'info'
|
||||
app.login_manager.session_protection = 'strong'
|
||||
|
|
@ -753,10 +755,17 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
|
|||
"""User loader callback"""
|
||||
if app.auth != 'none':
|
||||
user = app.uhandler.user(userid)
|
||||
if not user:
|
||||
return None
|
||||
if 'X-Language' in request.headers:
|
||||
language = request.headers.get('X-Language')
|
||||
user.language = language
|
||||
session['language'] = language
|
||||
if '_id' not in session:
|
||||
from flask_login import login_user
|
||||
# if _id is not in session, it means we loaded the user from
|
||||
# cache/db using the remember cookie so we need to login it
|
||||
login_user(user, remember=user.is_authenticated, fresh=False)
|
||||
_check_session(user, request)
|
||||
return user
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -778,6 +778,30 @@ def diag(client, host, tips):
|
|||
bconfsrv = app.conf.options.get('Burp', {}).get('bconfsrv') or \
|
||||
getattr(app.client, 'burpconfsrv')
|
||||
|
||||
try:
|
||||
app.client.status()
|
||||
except Exception as e:
|
||||
if 'Unable to spawn burp process' in str(e):
|
||||
try:
|
||||
app.client._spawn_burp(verbose=True)
|
||||
except Exception as e:
|
||||
msg = str(e)
|
||||
else:
|
||||
msg = str(e)
|
||||
|
||||
if msg:
|
||||
click.echo(click.style(msg, fg='red'))
|
||||
if 'could not connect' in msg:
|
||||
click.echo(
|
||||
click.style(
|
||||
'It looks like your burp-client can not reach your '
|
||||
'burp-server. Please check both your \'server\' setting in '
|
||||
'your \'{}\' file and \'status_address\' in your \'{}\' '
|
||||
'file.'.format(bconfcli, bconfsrv),
|
||||
fg='yellow'
|
||||
)
|
||||
)
|
||||
|
||||
errors = False
|
||||
if os.path.exists(bconfcli):
|
||||
parser = app.client.get_parser()
|
||||
|
|
@ -844,7 +868,7 @@ def diag(client, host, tips):
|
|||
click.echo(
|
||||
click.style(
|
||||
'\'max_status_children\' is to low, you need to set it to '
|
||||
'15 or more. Please edit your {} file'.format(bconfsrv),
|
||||
'15 or more. Please edit your {} file.'.format(bconfsrv),
|
||||
fg='blue'
|
||||
)
|
||||
)
|
||||
|
|
@ -868,8 +892,8 @@ def diag(client, host, tips):
|
|||
confsrv.get('monitor_browse_cache'):
|
||||
click.echo(
|
||||
click.style(
|
||||
'For performance reasons, it is recommanded to enable the '
|
||||
'\'monitor_browse_cache\'',
|
||||
'For performance reasons, it is recommended to enable the '
|
||||
'\'monitor_browse_cache\'.',
|
||||
fg='yellow'
|
||||
)
|
||||
)
|
||||
|
|
@ -894,7 +918,7 @@ def diag(client, host, tips):
|
|||
click.echo(
|
||||
click.style(
|
||||
'Unable to find "clientconfdir" option. Something is wrong '
|
||||
'with your setup',
|
||||
'with your setup.',
|
||||
fg='yellow'
|
||||
)
|
||||
)
|
||||
|
|
@ -903,7 +927,7 @@ def diag(client, host, tips):
|
|||
if not os.path.exists(bconfagent) and bconfagent.startswith('/'):
|
||||
click.echo(
|
||||
click.style(
|
||||
'Unable to find the {} file'.format(bconfagent),
|
||||
'Unable to find the {} file.'.format(bconfagent),
|
||||
fg='yellow'
|
||||
)
|
||||
)
|
||||
|
|
@ -918,7 +942,7 @@ def diag(client, host, tips):
|
|||
click.style(
|
||||
'It looks like the passwords in the {} and the {} files '
|
||||
'mismatch. Burp-UI will not work properly until you fix '
|
||||
'this'.format(bconfcli, bconfagent),
|
||||
'this.'.format(bconfcli, bconfagent),
|
||||
fg='yellow'
|
||||
)
|
||||
)
|
||||
|
|
@ -926,7 +950,7 @@ def diag(client, host, tips):
|
|||
click.echo(
|
||||
click.style(
|
||||
'Unable to locate burp-server configuration: {} does not '
|
||||
'exist'.format(bconfsrv),
|
||||
'exist.'.format(bconfsrv),
|
||||
fg='red'
|
||||
),
|
||||
err=True
|
||||
|
|
@ -939,7 +963,7 @@ def diag(client, host, tips):
|
|||
click.style(
|
||||
'Some errors have been found in your configuration. '
|
||||
'Please make sure you ran this command with the right flags! '
|
||||
'(see --help for details)'.format(sys.argv[0], sys.argv[1]),
|
||||
'(see --help for details).'.format(sys.argv[0], sys.argv[1]),
|
||||
fg='red'
|
||||
),
|
||||
err=True
|
||||
|
|
@ -947,6 +971,7 @@ def diag(client, host, tips):
|
|||
else:
|
||||
click.echo(
|
||||
click.style(
|
||||
'\n'
|
||||
'Well, if you are sure about your settings, you can run the '
|
||||
'following command to help you setup your Burp-UI agent. '
|
||||
'(Note, the \'--dry\' flag is here to show you the '
|
||||
|
|
|
|||
|
|
@ -34,4 +34,5 @@ socketio = SocketIO(
|
|||
# revert stdout and stderr
|
||||
sys.stdout = _stdout
|
||||
sys.stderr = _stderr
|
||||
null.close()
|
||||
# null.flush()
|
||||
# null.close()
|
||||
|
|
|
|||
|
|
@ -235,7 +235,10 @@ class UserHandler(BUIhandler):
|
|||
if name not in self.users:
|
||||
self.change = self.basic.load_users()
|
||||
self.users[name] = BasicUser(self.basic, name)
|
||||
return self.users[name]
|
||||
ret = self.users[name]
|
||||
if not ret.active:
|
||||
return None
|
||||
return ret
|
||||
|
||||
@property
|
||||
def changed(self):
|
||||
|
|
|
|||
|
|
@ -10,12 +10,17 @@ from importlib import import_module
|
|||
from flask import session
|
||||
from six import iteritems
|
||||
from collections import OrderedDict
|
||||
from flask_login import AnonymousUserMixin
|
||||
|
||||
|
||||
class UserAuthHandler(BUIhandler):
|
||||
"""See :class:`burpui.misc.auth.interface.BUIhandler`"""
|
||||
def __init__(self, app=None):
|
||||
"""See :func:`burpui.misc.auth.interface.BUIhandler.__init__`"""
|
||||
"""See :func:`burpui.misc.auth.interface.BUIhandler.__init__`
|
||||
|
||||
:param app: Instance of the app we are running in
|
||||
:type app: :class:`burpui.server.BUIServer`
|
||||
"""
|
||||
self.app = app
|
||||
self.users = {}
|
||||
backends = []
|
||||
|
|
@ -59,6 +64,14 @@ class UserAuthHandler(BUIhandler):
|
|||
def user(self, name=None, refresh=False):
|
||||
"""See :func:`burpui.misc.auth.interface.BUIhandler.user`"""
|
||||
key = session_manager.get_session_id() or name
|
||||
if key != name and is_uuid(name) and name in self.users and \
|
||||
not session_manager.session_expired_by_id(name):
|
||||
usr = self.users[name]
|
||||
usr.id = key
|
||||
self.users[key] = usr
|
||||
del self.users[name]
|
||||
session_manager.session_import_from(name)
|
||||
session['authenticated'] = True
|
||||
if not key:
|
||||
return None
|
||||
if refresh and key in self.users:
|
||||
|
|
@ -67,7 +80,7 @@ class UserAuthHandler(BUIhandler):
|
|||
session_manager.session_expired()
|
||||
if key not in self.users:
|
||||
ret = UserHandler(self.app, self.backends, name, key)
|
||||
if not ret.name:
|
||||
if not ret.name or not ret.active:
|
||||
return None
|
||||
self.users[key] = ret
|
||||
return ret
|
||||
|
|
@ -108,6 +121,36 @@ class ACLproxy(BUIacl):
|
|||
return self.acl.is_server_allowed(self.username, server)
|
||||
|
||||
|
||||
class ACLanon(BUIacl):
|
||||
def is_admin(self):
|
||||
return False
|
||||
|
||||
def is_moderator(self):
|
||||
return False
|
||||
|
||||
def is_client_allowed(self, client, server=None):
|
||||
return False
|
||||
|
||||
def is_server_allowed(self, server):
|
||||
return False
|
||||
|
||||
|
||||
class BUIanon(AnonymousUserMixin):
|
||||
_acl = ACLanon()
|
||||
name = 'Unknown'
|
||||
|
||||
def login(self, passwd=None):
|
||||
return False
|
||||
|
||||
@property
|
||||
def acl(self):
|
||||
return self._acl
|
||||
|
||||
@property
|
||||
def is_admin(self):
|
||||
return False
|
||||
|
||||
|
||||
class UserHandler(BUIuser):
|
||||
"""See :class:`burpui.misc.auth.interface.BUIuser`"""
|
||||
def __init__(self, app, backends=None, name=None, id=None):
|
||||
|
|
@ -133,6 +176,8 @@ class UserHandler(BUIuser):
|
|||
|
||||
for _, back in iteritems(self.backends):
|
||||
user = back.user(self.name)
|
||||
if not user:
|
||||
continue
|
||||
res = user.get_id()
|
||||
if res:
|
||||
self.active = True
|
||||
|
|
@ -186,6 +231,8 @@ class UserHandler(BUIuser):
|
|||
self.authenticated = False
|
||||
for name, back in iteritems(self.backends):
|
||||
u = back.user(self.name)
|
||||
if not u:
|
||||
continue
|
||||
res = u.get_id()
|
||||
if u.login(passwd):
|
||||
self.authenticated = True
|
||||
|
|
|
|||
|
|
@ -105,3 +105,13 @@ class BUIuser(with_metaclass(ABCMeta, UserMixin)):
|
|||
:returns: True if the user is admin, otherwise False
|
||||
"""
|
||||
return self.admin
|
||||
|
||||
def __str__(self):
|
||||
msg = UserMixin.__str__(self)
|
||||
return '{} (id: {}, admin: {}, authenticated: {}, active: {})'.format(
|
||||
msg,
|
||||
self.get_id(),
|
||||
self.is_admin,
|
||||
self.is_authenticated,
|
||||
self.is_active
|
||||
)
|
||||
|
|
|
|||
|
|
@ -236,7 +236,10 @@ class UserHandler(BUIhandler):
|
|||
"""See :func:`burpui.misc.auth.interface.BUIhandler.user`"""
|
||||
if name not in self.users:
|
||||
self.users[name] = LdapUser(self.ldap, name)
|
||||
return self.users[name]
|
||||
ret = self.users[name]
|
||||
if not ret.active:
|
||||
return None
|
||||
return ret
|
||||
|
||||
@property
|
||||
def loader(self):
|
||||
|
|
|
|||
|
|
@ -102,7 +102,10 @@ class UserHandler(BUIhandler):
|
|||
"""See :func:`burpui.misc.auth.interface.BUIhandler.user`"""
|
||||
if name not in self.users:
|
||||
self.users[name] = LocalUser(self.local, name)
|
||||
return self.users[name]
|
||||
ret = self.users[name]
|
||||
if not ret.active:
|
||||
return None
|
||||
return ret
|
||||
|
||||
@property
|
||||
def loader(self):
|
||||
|
|
|
|||
|
|
@ -489,6 +489,30 @@ class BUIbackend(with_metaclass(ABCMeta, object)):
|
|||
"""
|
||||
raise NotImplementedError("Sorry, the current Backend does not implement this method!") # pragma: no cover
|
||||
|
||||
# @abstractmethod
|
||||
# def get_client_status(self, client=None, agent=None):
|
||||
# """The :func:`burpui.misc.backend.interface.BUIbackend.get_client_status`
|
||||
# function returns the status of a given client with its last stats.
|
||||
#
|
||||
# :param client: What client status do we want
|
||||
# :type client: str
|
||||
# :param agent: What server to ask (only in multi-agent mode)
|
||||
# :type agent: str
|
||||
#
|
||||
# :returns: The last status of a given client
|
||||
#
|
||||
# Example::
|
||||
#
|
||||
# {
|
||||
# "name": "client1",
|
||||
# "state": "idle",
|
||||
# "percent": null,
|
||||
# "phase": null,
|
||||
# }
|
||||
#
|
||||
# """
|
||||
# raise NotImplementedError("Sorry, the current Backend does not implement this method!") # pragma: no cover
|
||||
|
||||
@abstractmethod
|
||||
def get_client_status(self, client=None, agent=None):
|
||||
"""The :func:`burpui.misc.backend.interface.BUIbackend.get_client_status`
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ def calendar(server=None, client=None):
|
|||
@login_required
|
||||
def settings(server=None, conf=None):
|
||||
# Only the admin can edit the configuration
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
abort(403)
|
||||
if not conf:
|
||||
try:
|
||||
|
|
@ -124,7 +124,7 @@ def settings(server=None, conf=None):
|
|||
@login_required
|
||||
def admin():
|
||||
# Only the admin can access this page
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
abort(403)
|
||||
return render_template('admin.html', admin=True, ng_controller='AdminCtrl')
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ def me():
|
|||
@login_required
|
||||
def cli_settings(server=None, client=None, conf=None):
|
||||
# Only the admin can edit the configuration
|
||||
if hasattr(current_user, 'acl') and not current_user.acl.is_admin():
|
||||
if not current_user.is_anonymous and not current_user.acl.is_admin():
|
||||
abort(403)
|
||||
if not conf:
|
||||
try:
|
||||
|
|
@ -404,7 +404,7 @@ def login():
|
|||
user = bui.uhandler.user(form.username.data, refresh)
|
||||
# at the time the context is loaded, the locale is not set
|
||||
refresh_babel()
|
||||
if user.is_active and user.login(form.password.data):
|
||||
if user and user.is_active and user.login(form.password.data):
|
||||
login_user(user, remember=form.remember.data)
|
||||
flash(_('Logged in successfully'), 'success')
|
||||
session_manager.store_session(
|
||||
|
|
|
|||
|
|
@ -130,6 +130,9 @@ class BUIServer(Flask):
|
|||
|
||||
@property
|
||||
def logger(self):
|
||||
"""
|
||||
:rtype: :class:`logging.Logger`
|
||||
"""
|
||||
return self._logger
|
||||
|
||||
def setup(self, conf=None, unittest=False, cli=False):
|
||||
|
|
|
|||
|
|
@ -108,6 +108,24 @@ class SessionManager(object):
|
|||
db.session.rollback()
|
||||
session['persistent'] = remember
|
||||
|
||||
def session_import_from(self, old_id):
|
||||
"""Import session from a given id"""
|
||||
self.session_update_id(old_id, self.get_session_id())
|
||||
|
||||
def session_update_id(self, old_id, new_id):
|
||||
"""Import session from a given id"""
|
||||
if self.session_managed():
|
||||
from .ext.sql import db
|
||||
from .models import Session
|
||||
old_session = Session.query.filter_by(uuid=old_id).first()
|
||||
if old_session:
|
||||
old_session.uuid = new_id
|
||||
try:
|
||||
db.session.commit()
|
||||
except:
|
||||
db.session.rollback()
|
||||
session['persistent'] = old_session.permanent
|
||||
|
||||
def session_in_db(self):
|
||||
"""Tell if the current session exists in db"""
|
||||
if self.session_managed():
|
||||
|
|
@ -209,8 +227,6 @@ class SessionManager(object):
|
|||
|
||||
def invalidate_current_session(self):
|
||||
"""Ivalidate current session"""
|
||||
if 'authenticated' in session:
|
||||
session.pop('authenticated')
|
||||
id = getattr(session, 'sid', None)
|
||||
session.clear()
|
||||
# simulate a logout to clear cookies
|
||||
|
|
|
|||
|
|
@ -370,6 +370,7 @@ $('#perform-revoke').on('click', function(e) {
|
|||
if ($me.data('multi')) {
|
||||
var rows = _sessions_table.api().rows( { selected: true } ).data();
|
||||
var current = undefined;
|
||||
var requests = [];
|
||||
var last;
|
||||
$.each(rows, function(i, row) {
|
||||
if (row.current) {
|
||||
|
|
@ -377,12 +378,18 @@ $('#perform-revoke').on('click', function(e) {
|
|||
return;
|
||||
}
|
||||
last = revoke_session(row.uuid, false);
|
||||
requests.push(last);
|
||||
});
|
||||
if (current) {
|
||||
window.location = '{{ url_for("view.logout") }}';
|
||||
return;
|
||||
$.when(requests).done(function() {
|
||||
window.location = '{{ url_for("view.logout") }}';
|
||||
return;
|
||||
});
|
||||
} else {
|
||||
$.when(requests).done(function() {
|
||||
_sessions();
|
||||
});
|
||||
}
|
||||
last.done(function() { _sessions(); });
|
||||
return;
|
||||
}
|
||||
if ($me.data('current')) {
|
||||
|
|
|
|||
|
|
@ -1214,7 +1214,7 @@ msgstr "Réstaurer sur un autre client "
|
|||
#: burpui/templates/client-browse.html:109
|
||||
#: burpui/templates/clients-report.html:35
|
||||
msgid "none"
|
||||
msgstr "néan"
|
||||
msgstr "néant"
|
||||
|
||||
#: burpui/templates/client-browse.html:115
|
||||
msgid "Whether to overwrite existing files"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue