Skip to content
Commits on Source (26)
*.pyc
burpui-dev.cfg
devel.sh
*.egg*
dist
include LICENSE
include README.md
include VERSION
include burpui.cfg
include burp-ui.py
include share/burpui/etc/burpui.cfg
recursive-include burpui *
# Build Status
[![build status](http://ci.ziirish.me/projects/1/status.png?ref=master)](http://ci.ziirish.me/projects/1?ref=master)
# Requirements
For LDAP authentication (optional), we need the `simpleldap` module that
requires the following packages on Debian:
```
aptitude install libsasl2-dev libldap2-dev python-dev
```
Then we install the module itself:
```
pip install simpleldap
```
# Installation
Burp-UI is written in Python with the [Flask](http://flask.pocoo.org/) micro-framework.
The easiest way to install Flask is to use `pip`.
On Debian, you can install `pip` with the following command:
```
aptitude install python-pip
```
Once `pip` is installed, you can install `Flask` and the other requirements this
way:
```
pip install Flask
pip install flask-login
pip install WTForms
pip install Flask-WTF
```
Then you need to download the sources.
For example:
```
git clone http://git.ziirish.me/ziirish/burp-ui.git
```
You can setup various parameters in the [burpui.cfg](burpui.cfg) file.
Then you can run `burp-ui`: `python burp-ui.py`
By default, `burp-ui` listens on all interfaces (including IPv6) on port 5000.
You can then point your browser to http://127.0.0.1:5000/
# Notes
Please feel free to report any issues on my [gitlab](https://git.ziirish.me/ziirish/burp-ui/issues)
I have closed the *github tracker* to have a unique tracker system.
# TODO
Here is a non-exhaustive list of things I'd like to add:
* Authentication so that only admins can access to burp stats.
* server-initiated restoration (with burp, you can create a special file that triggers
a restoration when the client contacts the server the next time. In this case the
client must accepts server-initiated restoration).
* burp-server configuration front-end (so that you can configure your burp server
within burp-ui).
* More statistics.
* etc.
Also note that in the future, I'd like to write a burp-client GUI.
But I didn't think yet of what to do.
# Licenses
Burp-UI is released under the BSD 3-clause [License](LICENSE).
But this project is built on top of other tools listed here:
- [d3.js](http://d3js.org/) ([BSD](burpui/static/d3/LICENSE))
- [nvd3.js](http://nvd3.org/) ([Apache](burpui/static/nvd3/LICENSE.md))
- [jQuery](http://jquery.com/) ([MIT](burpui/static/jquery/MIT-LICENSE.txt))
- [jQuery-UI](http://jqueryui.com/) ([MIT](burpui/static/jquery-ui/MIT-LICENSE.txt))
- [fancytree](https://github.com/mar10/fancytree) ([MIT](burpui/static/fancytree/MIT-LICENSE.txt))
- [bootstrap](http://getbootstrap.com/) ([MIT](burpui/static/bootstrap/LICENSE))
- [typeahead](http://twitter.github.io/typeahead.js/) ([MIT](burpui/static/typeahead/LICENSE))
- [bootswatch](http://bootswatch.com/) ([MIT](burpui/static/bootstrap/bootswatch.LICENSE))
Also note that this project is made with the Awesome [Flask](http://flask.pocoo.org/) micro-framework.
# Thanks
Special Thanks to Graham Keeling for its great software! This project would not
exist without [Burp](http://burp.grke.org/).
......@@ -35,29 +35,20 @@ On Debian, you can install ``pip`` with the following command:
aptitude install python-pip
Once ``pip`` is installed, you can install ``Flask`` and the other requirements this
way:
Once ``pip`` is installed, you can install ``Burp-UI`` this way:
::
pip install Flask
pip install flask-login
pip install WTForms
pip install Flask-WTF
Then you need to download the sources.
For example:
::
git clone http://git.ziirish.me/ziirish/burp-ui.git
pip install burp-ui
You can setup various parameters in the `burpui.cfg`_ file.
This file can be specified with the ``-c`` flag or should be present in
``/etc/burp/burpui.cfg``.
By default ``Burp-UI`` ships with a default file located in
``$BURPUIDIR/../share/burpui/etc/burpui.cfg``.
Then you can run ``burp-ui``: ``python burp-ui.py``
Then you can run ``burp-ui``: ``burp-ui``
By default, ``burp-ui`` listens on all interfaces (including IPv6) on port 5000.
......@@ -89,14 +80,14 @@ Burp-UI is released under the BSD 3-clause `License`_.
But this project is built on top of other tools listed here:
- `d3.js <http://d3js.org/>`_ (`BSD <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/d3/LICENSE>`_)
- `nvd3.js <http://nvd3.org/>`_ (`Apache <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/nvd3/LICENSE.md>`_)
- `jQuery <http://jquery.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/jquery/MIT-LICENSE.txt>`_)
- `jQuery-UI <http://jqueryui.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/jquery-ui/MIT-LICENSE.txt>`_)
- `fancytree <https://github.com/mar10/fancytree>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/fancytree/MIT-LICENSE.txt>`_)
- `bootstrap <http://getbootstrap.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/bootstrap/LICENSE>`_)
- `typeahead <http://twitter.github.io/typeahead.js/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/typeahead/LICENSE>`_)
- `bootswatch <http://bootswatch.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/bootstrap/bootswatch.LICENSE>`_)
- `d3.js <http://d3js.org/>`_ (`BSD <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/d3/LICENSE>`__)
- `nvd3.js <http://nvd3.org/>`_ (`Apache <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/nvd3/LICENSE.md>`__)
- `jQuery <http://jquery.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/jquery/MIT-LICENSE.txt>`__)
- `jQuery-UI <http://jqueryui.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/jquery-ui/MIT-LICENSE.txt>`__)
- `fancytree <https://github.com/mar10/fancytree>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/fancytree/MIT-LICENSE.txt>`__)
- `bootstrap <http://getbootstrap.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/bootstrap/LICENSE>`__)
- `typeahead <http://twitter.github.io/typeahead.js/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/typeahead/LICENSE>`__)
- `bootswatch <http://bootswatch.com/>`_ (`MIT <http://git.ziirish.me/ziirish/burp-ui/blob/master/burpui/static/bootstrap/bootswatch.LICENSE>`__)
Also note that this project is made with the Awesome `Flask`_ micro-framework.
......
#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys
import os
import os.path
from optparse import OptionParser
sys.path.append('{0}/..'.format(os.path.join(os.path.dirname(os.path.realpath(__file__)))))
from burpui import app, bui
if __name__ == '__main__':
"""
Main function
"""
parser = OptionParser()
parser.add_option('-v', '--verbose', dest='log', help='verbose output', action='store_true')
parser.add_option('-c', '--config', dest='config', help='configuration file', metavar='CONFIG')
(options, args) = parser.parse_args()
d = options.log
app.config['DEBUG'] = d
if options.config:
if os.path.isfile(options.config):
conf = options.config
app.config['CFG'] = conf
else:
raise IOError('File not found: \'{0}\''.format(options.config))
else:
conf_files = ['/etc/burp/burpui.cfg', os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'share', 'burpui', 'etc', 'burpui.cfg')]
for p in conf_files:
app.logger.debug('Trying file \'%s\'', p)
if os.path.isfile(p):
app.config['CFG'] = p
app.logger.debug('Using file \'%s\'', p)
break
bui.setup(app.config['CFG'])
bui.run(d)
#!/usr/bin/env python
# -*- coding: utf8 -*-
import os
from optparse import OptionParser
from burpui import app, bui
if __name__ == '__main__':
"""
Main function
"""
parser = OptionParser()
parser.add_option('-v', '--verbose', dest='log', help='verbose output', action='store_true')
parser.add_option('-c', '--config', dest='config', help='configuration file', metavar='CONFIG')
(options, args) = parser.parse_args()
d = options.log
app.config['DEBUG'] = d
if options.config:
conf = options.config
else:
conf = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'burpui.cfg')
app.config['CFG'] = conf
bui.setup(conf)
bui.run(d)
bin/burp-ui
\ No newline at end of file
[Global]
# On which port is the application listening
port: 5000
# On which address is the application listening
# '::' is the default for all IPv6
bind: ::
# burp status port
bport: 4972
# burp status address
bhost: 127.0.0.1
# enable SSL
ssl: false
# ssl cert
sslcert: /etc/burp/ssl_cert-server.pem
# ssl key
sslkey: /etc/burp/ssl_cert-server.key
# burp server version (currently only burp 1.x is implemented)
version: 1
# authentication plugin (mandatory)
# list the misc/auth directory to see the available backends
auth: ldap
[UI]
# refresh interval of the pages in seconds
refresh: 15
# ldapauth specific options
[LDAP]
# LDAP host
host: 127.0.0.1
# LDAP filter to list existing users
#filter: &(burpui=1)
# LDAP base
base: ou=users,dc=example,dc=com
# Binddn to list existing users
binddn: cn=admin,dc=example,dc=com
# Bindpw to list existing users
bindpw: Sup3rS3cr3tPa$$w0rd
# basicauth specific options
#[BASIC]
#admin: password
#user1: otherpassword
share/burpui/etc/burpui.cfg
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf8 -*-
"""
Burp-UI is a web-ui for burp backup written in python with Flask and
jQuery/Bootstrap
"""
__title__ = 'burp-ui'
__version__ = '0.0.1'
__author__ = 'Benjamin SANS (Ziirish)'
__license__ = 'BSD 3-clause'
import os
from flask import Flask
from flask.ext.login import LoginManager
from burpui.server import Server as BurpUI
# First, we setup the app
app = Flask(__name__)
app.config['CFG'] = os.path.join(app.root_path, '../burpui.cfg')
app.config['CFG'] = None
app.secret_key = 'VpgOXNXAgcO81xFPyWj07ppN6kExNZeCDRShseNzFKV7ZCgmW2/eLn6xSlt7pYAVBj12zx2Vv9Kw3Q3jd1266A=='
app.jinja_env.globals.update(isinstance=isinstance,list=list)
# We initialize the core
bui = BurpUI(app)
# And the login_manager
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
# Then we load our routes
import burpui.routes
# -*- coding: utf8 -*-
from flask_wtf import Form
from wtforms import TextField, PasswordField, validators
from wtforms import TextField, PasswordField, BooleanField, validators
class LoginForm(Form):
username = TextField('Username', [validators.Length(min=2, max=25)])
password = PasswordField('Password', [validators.Required()])
remember = BooleanField('Remember me', [validators.Optional()])
......@@ -2,7 +2,11 @@
from flask.ext.login import UserMixin
from burpui.misc.auth.interface import BUIhandler, BUIuser
try:
import simpleldap
except ImportError:
raise ImportError('Unable to load \'simpleldap\' module')
import ConfigParser
class LdapLoader:
......@@ -18,8 +22,10 @@ class LdapLoader:
self.base = c.get('LDAP', 'base')
self.binddn = c.get('LDAP', 'binddn')
self.bindpw = c.get('LDAP', 'bindpw')
except ConfigParser.NoOptionError:
self.app.logger.error("Missing option")
except ConfigParser.NoOptionError, e:
self.app.logger.error(str(e))
except ConfigParser.NoSectionError, e:
self.app.logger.error(str(e))
self.app.logger.info('LDAP host: %s', self.host)
self.app.logger.info('LDAP filter: %s', self.filt)
......
......@@ -3,9 +3,13 @@ import re
import socket
import time
import datetime
import ConfigParser
from burpui.misc.utils import human_readable as _hr
from burpui.misc.backend.interface import BUIbackend
from burpui.misc.backend.interface import BUIbackend, BUIserverException
g_burpport = 4972
g_burphost = '127.0.0.1'
class Burp(BUIbackend):
states = {
......@@ -48,11 +52,25 @@ class Burp(BUIbackend):
'path'
]
def __init__(self, app=None, host='127.0.0.1', port=4972):
def __init__(self, app=None, host='127.0.0.1', port=4972, conf=None):
global g_burpport, g_burphost
self.app = app
self.host = host
self.port = port
self.running = []
if conf:
config = ConfigParser.ConfigParser({'bport': g_burpport, 'bhost': g_burphost})
with open(conf) as fp:
config.readfp(fp)
try:
self.port = config.getint('Burp1', 'bport')
self.host = config.get('Burp1', 'bhost')
except ConfigParser.NoOptionError, e:
self.app.logger.error(str(e))
except ConfigParser.NoSectionError, e:
self.app.logger.error(str(e))
self.app.logger.info('burp port: %d', self.port)
self.app.logger.info('burp host: %s', self.host)
"""
Utilities functions
......@@ -89,7 +107,7 @@ class Burp(BUIbackend):
return r
except socket.error:
self.app.logger.error('Cannot contact burp server at %s:%s', self.host, self.port)
return r
raise BUIserverException('Cannot contact burp server at {0}:{1}'.format(self.host, self.port))
def parse_backup_log(self, f, n, c=None):
"""
......@@ -230,7 +248,10 @@ class Burp(BUIbackend):
"""
if not name:
return False
try:
f = self.status('c:{0}\n'.format(name))
except BUIserverException:
return False
for line in f:
r = re.search('^{0}\s+\d\s+(\S)'.format(name), line)
if r and r.group(1) not in [ 'i', 'c', 'C' ]:
......@@ -243,7 +264,11 @@ class Burp(BUIbackend):
running a backup
"""
r = []
for c in self.get_all_clients():
try:
cls = self.get_all_clients()
except BUIserverException:
return r
for c in cls:
if self.is_backup_running(c['name']):
r.append(c['name'])
self.running = r
......
#raise NotImplementedError("Sorry, the current Backend does not implement this method!")
# -*- coding: utf8 -*-
class BUIbackend:
def __init__(self, app=None, host='127.0.0.1', port=4972):
......@@ -29,3 +29,6 @@ class BUIbackend:
def get_tree(self, name=None, backup=None, root=None):
raise NotImplementedError("Sorry, the current Backend does not implement this method!")
class BUIserverException(Exception):
pass
......@@ -7,49 +7,57 @@ from flask.ext.login import login_user, login_required, logout_user, current_use
from burpui import app, bui, login_manager
from burpui.forms import LoginForm
from burpui.misc.utils import human_readable as _hr
from burpui.misc.backend.interface import BUIserverException
@login_manager.user_loader
def load_user(userid):
if bui.auth != 'none':
return bui.uhandler.user(userid)
return None
@app.route('/login', methods=['POST', 'GET'])
def login():
form = LoginForm(request.form)
if form.validate_on_submit():
user = bui.uhandler.user(form.username.data)
app.logger.info('%s active: %s', form.username.data, user.active)
if user.active and user.login(form.username.data, passwd=form.password.data):
login_user(user)
flash('Logged in successfully.')
return redirect(url_for('test_login'))
login_user(user, remember=form.remember.data)
flash('Logged in successfully', 'success')
return redirect(request.args.get("next") or url_for('home'))
return render_template('login.html', form=form, login=True)
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))
@app.route('/test_login')
@login_required
def test_login():
return render_template('test-login.html', login=True, user=current_user.name)
return redirect(url_for('home'))
"""
Here is the API
The whole API returns JSON-formated data
"""
@app.route('/api/running-clients.json')
@login_required
def running_clients():
"""
WebServer: return a list of running clients
API: running_clients
:returns: a list of running clients
"""
r = bui.cli.is_one_backup_running()
return jsonify(results=r)
@app.route('/api/render-live-template', methods=['GET'])
@app.route('/api/render-live-template/<name>')
@login_required
def render_live_tpl(name=None):
"""
API: render_live_tpl
:param name: the client name if any. You can also use the GET parameter
'name' to achieve the same thing
:returns: HTML that should be included directly into the page
"""
c = request.args.get('name')
if not name and not c:
abort(500)
......@@ -57,50 +65,73 @@ def render_live_tpl(name=None):
name = c
if name not in bui.cli.running:
abort(404)
try:
counters = bui.cli.get_counters(name)
except BUIserverException:
counters = []
return render_template('live-monitor-template.html', cname=name, counters=counters)
@app.route('/api/live.json')
@login_required
def live():
"""
WebServer: return the live status of the server
API: live
:returns: the live status of the server
"""
r = []
for c in bui.cli.is_one_backup_running():
s = {}
s['client'] = c
try:
s['status'] = bui.cli.get_counters(c)
except BUIserverException:
s['status'] = []
r.append(s)
return jsonify(results=r)
@app.route('/api/running.json')
@login_required
def backup_running():
"""
WebService: return true if at least one backup is running
API: backup_running
:returns: true if at least one backup is running
"""
j = bui.cli.is_one_backup_running()
r = len(j) > 0
return jsonify(results=r)
@app.route('/api/client-tree.json/<name>/<int:backup>', methods=['GET'])
@login_required
def client_tree(name=None, backup=None):
"""
WebService: return a specific client files tree
:param name: the client name (mandatory)
:param backup: the backup number (mandatory)
"""
j = []
if not name or not backup:
return jsonify(results=j)
root = request.args.get('root')
try:
j = bui.cli.get_tree(name, backup, root)
except BUIserverException, e:
err = [[2, str(e)]]
return jsonify(notif=err)
return jsonify(results=j)
@app.route('/api/clients-report.json')
@login_required
def clients_report_json():
"""
WebService: return a JSON with global stats
"""
j = []
try:
clients = bui.cli.get_all_clients()
except BUIserverException, e:
err = [[2, str(e)]]
return jsonify(notif=err)
cl = []
ba = []
for c in clients:
......@@ -117,36 +148,57 @@ def clients_report_json():
@app.route('/api/client-stat.json/<name>')
@app.route('/api/client-stat.json/<name>/<int:backup>')
@login_required
def client_stat_json(name=None, backup=None):
"""
WebService: return a specific client detailed report
"""
j = []
if not name:
return jsonify(results=j)
err = [[1, 'No client defined']]
return jsonify(notif=err)
if backup:
try:
f = bui.cli.status('c:{0}:b:{1}:f:log.gz\n'.format(name, backup))
except BUIserverException, e:
err = [[2, str(e)]]
return jsonify(notif=err)
j = bui.cli.parse_backup_log(f, backup)
else:
for c in bui.cli.get_client(name):
try:
cl = bui.cli.get_client(name)
except BUIserverException, e:
err = [[2, str(e)]]
return jsonify(notif=err)
for c in cl:
f = bui.cli.status('c:{0}:b:{1}:f:log.gz\n'.format(name, c['number']))
j.append(bui.cli.parse_backup_log(f, c['number']))
return jsonify(results=j)
@app.route('/api/client.json/<name>')
@login_required
def client_json(name=None):
"""
WebService: return a specific client backups overview
"""
try:
j = bui.cli.get_client(name)
except BUIserverException, e:
err = [[2, str(e)]]
return jsonify(notif=err)
return jsonify(results=j)
@app.route('/api/clients.json')
@login_required
def clients():
"""
WebService: return a JSON listing all clients
"""
try:
j = bui.cli.get_all_clients()
except BUIserverException, e:
err = [[2, str(e)]]
return jsonify(notif=err)
return jsonify(results=j)
"""
......@@ -181,17 +233,19 @@ And here is the main site
@app.route('/live-monitor')
@app.route('/live-monitor/<name>')
@login_required
def live_monitor(name=None):
"""
Live status monitor view
"""
if not bui.cli.running:
flash('Sorry, there are no running backups')
flash('Sorry, there are no running backups', 'warning')
return redirect(url_for('home'))
return render_template('live-monitor.html', live=True, cname=name)
@app.route('/client-browse/<name>', methods=['GET'])
@app.route('/client-browse/<name>/<int:backup>')
@login_required
def client_browse(name=None, backup=None):
"""
Browse a specific backup of a specific client
......@@ -202,6 +256,7 @@ def client_browse(name=None, backup=None):
return render_template('client-browse.html', tree=True, backup=True, overview=True, cname=name, nbackup=backup)
@app.route('/client-report/<name>')
@login_required
def client_report(name=None):
"""
Specific client report
......@@ -212,6 +267,7 @@ def client_report(name=None):
return render_template('client-report.html', client=True, report=True, cname=name)
@app.route('/clients-report')
@login_required
def clients_report():
"""
Global report
......@@ -220,6 +276,7 @@ def clients_report():
@app.route('/backup-report/<name>', methods=['GET'])
@app.route('/backup-report/<name>/<int:backup>', methods=['GET'])
@login_required
def backup_report(name=None, backup=None):
"""
Backup specific report
......@@ -230,6 +287,7 @@ def backup_report(name=None, backup=None):
@app.route('/client', methods=['GET'])
@app.route('/client/<name>')
@login_required
def client(name=None):
"""
Specific client overview
......@@ -243,6 +301,7 @@ def client(name=None):
return render_template('client.html', client=True, overview=True, cname=c)
@app.route('/')
@login_required
def home():
"""
Home page
......
......@@ -2,8 +2,6 @@
import ConfigParser
import sys
g_burpport = 4972
g_burphost = '127.0.0.1'
g_port = 5000
g_bind = '::'
g_refresh = 15
......@@ -11,7 +9,7 @@ g_ssl = False
g_sslcert = ''
g_sslkey = ''
g_version = 1
g_auth = 'ldap'
g_auth = 'basic'
class Server:
def __init__(self, app=None):
......@@ -19,19 +17,20 @@ class Server:
self.app = app
def setup(self, conf=None):
global g_refresh, g_burpport, g_burphost, g_port, g_bind, g_ssl, g_sslcert, g_sslkey, g_version, g_auth
global g_refresh, g_port, g_bind, g_ssl, g_sslcert, g_sslkey, g_version, g_auth
self.sslcontext = None
if not conf:
conf = self.app.config['CFG']
config = ConfigParser.ConfigParser({'bport': g_burpport, 'bhost': g_burphost, 'port': g_port,
'bind': g_bind, 'refresh': g_refresh, 'ssl': g_ssl, 'sslcert': g_sslcert,
if not conf:
raise IOError('No configuration file found')
config = ConfigParser.ConfigParser({'port': g_port,'bind': g_bind,
'refresh': g_refresh, 'ssl': g_ssl, 'sslcert': g_sslcert,
'sslkey': g_sslkey, 'version': g_version, 'auth': g_auth})
with open(conf) as fp:
config.readfp(fp)
try:
self.burpport = config.getint('Global', 'bport')
self.burphost = config.get('Global', 'bhost')
self.port = config.getint('Global', 'port')
self.bind = config.get('Global', 'bind')
self.vers = config.getint('Global', 'version')
......@@ -42,20 +41,23 @@ class Server:
self.ssl = False
self.sslcert = config.get('Global', 'sslcert')
self.sslkey = config.get('Global', 'sslkey')
self.auth = config.get('Global', 'auth')
if self.auth != 'none':
try:
mod = __import__('burpui.misc.auth.{0}'.format(config.get('Global', 'auth')), fromlist=['UserHandler'])
UserHandler = mod.UserHandler
self.uhandler = UserHandler(self.app)
except Exception:
self.app.logger.error('Import Exception, module \'%s\'', config.get('Global', 'auth'))
except Exception, e:
self.app.logger.error('Import Exception, module \'%s\': %s', config.get('Global', 'auth'), str(e))
sys.exit(1)
else:
# I know that's ugly, but hey, I need it!
self.app.login_manager._login_disabled = True
except ConfigParser.NoOptionError:
self.app.logger.error("Missing option")
self.app.config['REFRESH'] = config.getint('UI', 'refresh')
self.app.logger.info('burp port: %d', self.burpport)
self.app.logger.info('burp host: %s', self.burphost)
self.app.logger.info('burp version: %d', self.vers)
self.app.logger.info('listen port: %d', self.port)
self.app.logger.info('bind addr: %s', self.bind)
......@@ -67,9 +69,9 @@ class Server:
try:
mod = __import__('burpui.misc.backend.burp{0}'.format(self.vers), fromlist=['Burp'])
Client = mod.Burp
self.cli = Client(self.app, self.burphost, self.burpport)
except Exception:
self.app.logger.error('Failed loading backend for Burp version %d', self.vers)
self.cli = Client(self.app, conf=conf)
except Exception, e:
self.app.logger.error('Failed loading backend for Burp version %d: %s', self.vers, str(e))
sys.exit(2)
self.init = True
......
......@@ -203,3 +203,48 @@ svg text {
animation: blink 1s step-start 0s infinite;
-webkit-animation: blink 1s step-start 0s infinite;
}
.wrapper {
margin-top: 80px;
margin-bottom: 80px;
}
.form-signin {
background: linear-gradient(#8a9196, #7a8288 60%, #70787d);
max-width: 380px;
padding: 15px 35px 45px;
margin: 0 auto;
border: 1px solid rgba(0,0,0,0.1);
.checkbox {
margin-bottom: 30px;
}
.form-control {
position: relative;
font-size: 16px;
height: auto;
padding: 10px;
@include box-sizing(border-box);
&:focus {
z-index: 2;
}
}
input[type="text"] {
margin-bottom: -1px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
input[type="password"] {
margin-bottom: 20px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
#search {
margin-right: 0.1em;
}
{% extends "layout.html" %}
{% block body %}
{% include "notifications.html" %}
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
{% include "small_topbar.html" %}
<ul class="breadcrumb" style="margin-bottom: 5px;">
......
{% extends "layout.html" %}
{% block body %}
{% include "notifications.html" %}
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
{% include "small_topbar.html" %}
<ul class="breadcrumb" style="margin-bottom: 5px;">
......