Commit 2c8e330a authored by Ziirish's avatar Ziirish

wait for the burp-server to be up and running while starting the agent

parent 935c4ca8
......@@ -18,6 +18,11 @@ Current
- Fix: issue `#268 <https://git.ziirish.me/ziirish/burp-ui/issues/268>`_
- `Full changelog <https://git.ziirish.me/ziirish/burp-ui/compare/0.6.0...master>`__
0.6.6 (04/01/2019)
------------------
- Fix: agent cannot start `#302 <https://git.ziirish.me/ziirish/burp-ui/issues/302>`__
0.6.5 (03/27/2019)
------------------
......
......@@ -13,6 +13,7 @@ import sys
import ssl
import json
import logging
import time
import trio
from ..exceptions import BUIserverException
......@@ -38,6 +39,7 @@ BUI_DEFAULTS = {
'sslkey': '',
'backend': 'burp2',
'password': 'azerty',
'init_wait': 15,
},
}
......@@ -50,10 +52,11 @@ class BurpHandler(BUIbackend):
foreign = BUIbackend.__abstractmethods__
BUIbackend.__abstractmethods__ = frozenset()
def __init__(self, backend='burp2', logger=None, conf=None):
def __init__(self, backend='burp2', logger=None, conf=None, init_wait=0):
self.backend_name = backend
self.is_async = backend == 'parallel'
self.logger = logger
wait = init_wait
top = __name__
if '.' in self.backend_name:
......@@ -70,8 +73,16 @@ class BurpHandler(BUIbackend):
else:
Client = mod.Burp
self.backend = Client(conf=conf)
stats = self.backend.statistics()
if 'alive' not in stats or not stats['alive']:
def __backend_alive():
stats = self.backend.statistics()
return 'alive' in stats and stats['alive']
alive = __backend_alive()
while not alive and wait > 0:
self.logger.debug("Waiting for the backend to become alive... {}/{}".format(init_wait - wait, init_wait))
time.sleep(1)
alive = __backend_alive()
wait -= 1
if not alive:
raise BUIserverException('Cannot talk to burp server')
except Exception as exc:
self.logger.error('Failed loading backend {}: {}'.format(self.backend_name, str(exc)), exc_info=exc, stack_info=True)
......@@ -117,9 +128,10 @@ class BUIAgent(BUIbackend):
self.sslcert = self.conf.safe_get('sslcert')
self.sslkey = self.conf.safe_get('sslkey')
self.password = self.conf.safe_get('password')
self.init_wait = self.conf.safe_get('init_wait', 'integer')
self.conf.setdefault('BUI_AGENT', True)
self.client = BurpHandler(self.backend, self.logger, self.conf)
self.client = BurpHandler(self.backend, self.logger, self.conf, self.init_wait)
def _ssl_context(self):
if not self.ssl:
......
......@@ -206,6 +206,8 @@ class MonitorPool:
'server_version': 'unknown',
'client_version': 'unknown'
}
if self.pool.empty():
await self.fill_pool()
while not self.pool.empty():
mon = await self.pool.get()
tmp.append(mon)
......
......@@ -224,9 +224,9 @@ class Burp(Burp2):
if self.init_wait:
exc = None
init_mon = Parallel(conf)
for _ in range(self.init_wait):
for i in range(self.init_wait):
try:
self.logger.warning('monitor not ready, waiting for it...')
self.logger.warning('monitor not ready, waiting for it... {}/{}'.format(i, self.init_wait))
trio.run(init_mon.conn)
if init_mon.connected:
break
......@@ -237,6 +237,8 @@ class Burp(Burp2):
self.logger.error('monitor not ready, giving up!')
raise exc
del init_mon
stats = self.statistics()
if 'alive' in stats and stats['alive']:
self.init_all()
def init_all(self):
......@@ -262,12 +264,18 @@ class Burp(Burp2):
def get_client_version(self, agent=None):
if self._client_version is None:
self._client_version = trio.run(self._async_request, 'client_version')
try:
self._client_version = trio.run(self._async_request, 'client_version')
except BUIserverException:
return ''
return self._client_version or ''
def get_server_version(self, agent=None):
if self._server_version is None:
self._server_version = trio.run(self._async_request, 'server_version')
try:
self._server_version = trio.run(self._async_request, 'server_version')
except BUIserverException:
return ''
return self._server_version or ''
async def _async_status(self, query='c:\n', timeout=None, cache=True, agent=None):
......@@ -285,8 +293,6 @@ class Burp(Burp2):
return await async_client.request(func, *args, **kwargs)
except (OSError, IOError) as exc:
raise BUIserverException(str(exc))
if not self._ready:
self.init_all()
@usetriorun
def status(self, query='c:\n', timeout=None, cache=True, agent=None):
......@@ -827,6 +833,12 @@ class Burp(Burp2):
# Make every "Burp" method async
class AsyncBurp(Burp):
@property
async def batch_list_supported(self):
if self._batch_list_supported is None:
self._batch_list_supported = json.loads(await self._async_request('batch_list_supported'))
return self._batch_list_supported
# this method must not be async!
@implement
def statistics(self, agent=None):
......@@ -877,6 +889,17 @@ class AsyncBurp(Burp):
"""
return await self._async_get_all_clients()
@implement
async def get_attr(self, name, default=None, agent=None):
"""See :func:`burpui.misc.backend.interface.BUIbackend.get_attr`"""
try:
try:
return await getattr(self, name, default)
except TypeError:
return getattr(self, name, default)
except AttributeError:
return default
def __getattribute__(self, name):
if name in BUIBACKEND_INTERFACE_METHODS or name in ['_guess_os']:
wrap = False
......
......@@ -129,14 +129,20 @@ class Monitor(object):
@property
def server_version(self):
if self._server_version is None:
self.status()
try:
self.status()
except BUIserverException:
return ''
return self._server_version or ''
@property
def alive(self):
# clients may be idle for some time, in that case we may need to start them again
if not self._proc_is_alive():
self._spawn_burp()
try:
self._spawn_burp()
except OSError:
pass
return self._proc_is_alive()
def _exit(self):
......
......@@ -113,6 +113,9 @@ section as below:
version = 1
# agent password
password = password
# time to wait at startup
# the burp server must be started before your agent
init_wait = 15
Each option is commented, but here is a more detailed documentation:
......@@ -125,6 +128,8 @@ Each option is commented, but here is a more detailed documentation:
- *version*: What version of `Burp`_ this `bui-agent`_ instance manages. (see
`Burp-UI versions <advanced_usage.html#versions>`__ for more details)
- *password*: The shared secret between the `Burp-UI`_ server and `bui-agent`_.
- *init_wait*: The time to wait for the backend to be alive (this is useful in
case you start every services at the same time).
As with `Burp-UI`_, you need a specific ``[Burp]`` section.
Please refer to the `Burp-UI versions <advanced_usage.html#options>`__
......
......@@ -31,6 +31,11 @@ v0.7.0
``:AUTH`` suffix (so ``BASIC`` becomes ``BASIC:AUTH``, etc.).
Please make sure you rename those sections accordingly so you won't be locked
out.
- **Breaking** - the ``bui-agent`` will now exit when its *system* requirements
are not met at startup time (that is: the burp-server must be up and running
and the burp-client used by burp-ui must be able to reach the burp-server).
A new timeout has been added though in order for ``bui-agent`` to wait for the
burp-server to be ready.
v0.6.0
------
......
......@@ -18,6 +18,9 @@ sslkey = /var/lib/burp/ssl/server/ssl_cert-server.key
backend = burp2
# agent password
password = azerty
# time to wait at startup
# the burp server must be started before your agent
init_wait = 15
[Security]
## This section contains some security options. Make sure you understand the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment