From 051b70cfde863f445a8bef53bce0f5d0b3822a3b Mon Sep 17 00:00:00 2001 From: ziirish Date: Wed, 16 Dec 2015 22:50:47 +0100 Subject: [PATCH] add: compat module with some tricks --- burpui/__init__.py | 5 +++ burpui/__main__.py | 3 ++ burpui/_compat.py | 66 ++++++++++++++++++++++++++++++++ burpui/agent.py | 5 +-- burpui/misc/acl/basic.py | 5 +-- burpui/misc/auth/basic.py | 6 +-- burpui/misc/auth/ldap.py | 8 +--- burpui/misc/backend/burp1.py | 5 +-- burpui/misc/backend/burp2.py | 5 +-- burpui/misc/backend/interface.py | 7 +--- burpui/server.py | 5 +-- 11 files changed, 84 insertions(+), 36 deletions(-) create mode 100644 burpui/_compat.py diff --git a/burpui/__init__.py b/burpui/__init__.py index 32ccaa4f..5bfdae5d 100644 --- a/burpui/__init__.py +++ b/burpui/__init__.py @@ -87,11 +87,14 @@ def init(conf=None, debug=0, logfile=None, gunicorn=True, unittest=False): from .server import BUIServer as BurpUI from .routes import view from .api import api, apibp + from ._compat import patch_json if gunicorn: from gevent import monkey monkey.patch_all() + patch_json() + # We initialize the core app = BurpUI() app.gunicorn = gunicorn @@ -191,6 +194,8 @@ def init(conf=None, debug=0, logfile=None, gunicorn=True, unittest=False): 'CACHE_REDIS_DB': 1 } ) + # clear cache at startup in case we removed or added servers + api.cache.clear() else: api.cache.init_app(app) diff --git a/burpui/__main__.py b/burpui/__main__.py index 4f867858..75f101eb 100644 --- a/burpui/__main__.py +++ b/burpui/__main__.py @@ -61,6 +61,9 @@ def server(options=None): def agent(options=None): from burpui.agent import BUIAgent as Agent + from burpui._compat import patch_json + + patch_json() if not options: options = parse_args(mode=False, name='bui-agent') diff --git a/burpui/_compat.py b/burpui/_compat.py new file mode 100644 index 00000000..6a5058f1 --- /dev/null +++ b/burpui/_compat.py @@ -0,0 +1,66 @@ +# -*- coding: utf8 -*- +""" +.. module:: burpui._compat + :platform: Unix + :synopsis: Burp-UI compatibility module. + +.. moduleauthor:: Ziirish + +""" +import sys +import os + +try: + import ConfigParser +except ImportError: + import configparser as ConfigParser + +IS_GUNICORN = 'gunicorn' in os.environ.get('SERVER_SOFTWARE', '') + +if IS_GUNICORN: + from gevent.local import local +else: + local = object + + +if sys.version_info[0] >= 3: + PY3 = True +else: + PY3 = False + +# maps module name -> attribute name -> original item +# e.g. "time" -> "sleep" -> built-in function sleep +saved = {} + + +# Borrowed from gevent in order to patch json +def patch_item(module, attr, newitem, newmodule=None): + NONE = object() + olditem = getattr(module, attr, NONE) + if olditem is not NONE: + saved.setdefault(module.__name__, {}).setdefault(attr, olditem) + if newmodule: + setattr(newmodule, 'ori_' + attr, olditem) + setattr(module, attr, newitem) + + +def patch_module(name, items=None): + toimport = items or [] + replace_module = __import__('burpui._' + name, fromlist=toimport) + module_name = name + module = __import__(module_name) + if items is None: + items = getattr(replace_module, '__implements__', None) + if items is None: + raise AttributeError('%r does not have __implements__' % replace_module) + for attr in items: + patch_item(module, attr, getattr(replace_module, attr), replace_module) + + +def patch_json(): + try: + import ujson + except ImportError: + # ujson is not available, we won't patch anything + return + patch_module('json', ['dumps', 'loads']) diff --git a/burpui/agent.py b/burpui/agent.py index d9c9b0ef..a5e9f54d 100644 --- a/burpui/agent.py +++ b/burpui/agent.py @@ -16,10 +16,6 @@ try: import ujson as json except ImportError: import json -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser try: import SocketServer except ImportError: @@ -28,6 +24,7 @@ except ImportError: from logging.handlers import RotatingFileHandler from .exceptions import BUIserverException from .misc.backend.interface import BUIbackend +from ._compat import ConfigParser from Queue import Queue diff --git a/burpui/misc/acl/basic.py b/burpui/misc/acl/basic.py index ce1c0ecb..28c2d77f 100644 --- a/burpui/misc/acl/basic.py +++ b/burpui/misc/acl/basic.py @@ -1,10 +1,7 @@ # -*- coding: utf8 -*- from .interface import BUIacl, BUIaclLoader +from ..._compat import ConfigParser -try: - import ConfigParser -except ImportError: # pragma: no cover - import configparser as ConfigParser import json diff --git a/burpui/misc/auth/basic.py b/burpui/misc/auth/basic.py index 11d29de9..a83d0005 100644 --- a/burpui/misc/auth/basic.py +++ b/burpui/misc/auth/basic.py @@ -1,10 +1,6 @@ # -*- coding: utf8 -*- from .interface import BUIhandler, BUIuser - -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser +from ..._compat import ConfigParser class BasicLoader: diff --git a/burpui/misc/auth/ldap.py b/burpui/misc/auth/ldap.py index b7285403..5c327d48 100644 --- a/burpui/misc/auth/ldap.py +++ b/burpui/misc/auth/ldap.py @@ -1,6 +1,8 @@ # -*- coding: utf8 -*- from six import viewitems + from .interface import BUIhandler, BUIuser +from ..._compat import ConfigParser import ssl @@ -9,12 +11,6 @@ try: except ImportError: raise ImportError('Unable to load \'ldap3\' module') -# python 3 compatibility -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser - class LdapLoader: """The :class:`burpui.misc.auth.ldap.LdapLoader` handles searching for and diff --git a/burpui/misc/backend/burp1.py b/burpui/misc/backend/burp1.py index 4e288aba..5928883f 100644 --- a/burpui/misc/backend/burp1.py +++ b/burpui/misc/backend/burp1.py @@ -21,10 +21,6 @@ try: import ujson as json except ImportError: import json -try: - import ConfigParser -except ImportError: # pragma: no cover - import configparser as ConfigParser from six import iteritems from pipes import quote @@ -33,6 +29,7 @@ from .interface import BUIbackend from ..parser.burp1 import Parser from ...utils import human_readable as _hr, BUIcompress from ...exceptions import BUIserverException +from ..._compat import ConfigParser if sys.version_info >= (3, 0): # pragma: no cover from urllib.parse import unquote diff --git a/burpui/misc/backend/burp2.py b/burpui/misc/backend/burp2.py index 0103f1a9..1ae6a9d9 100644 --- a/burpui/misc/backend/burp2.py +++ b/burpui/misc/backend/burp2.py @@ -10,10 +10,6 @@ try: import ujson as json except ImportError: import json -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser from six import iteritems from select import select @@ -22,6 +18,7 @@ from .burp1 import Burp as Burp1 from ..parser.burp2 import Parser from ...utils import human_readable as _hr from ...exceptions import BUIserverException +from ..._compat import ConfigParser if sys.version_info < (3, 3): TimeoutError = OSError diff --git a/burpui/misc/backend/interface.py b/burpui/misc/backend/interface.py index 75d5ed8f..ae2ceb6b 100644 --- a/burpui/misc/backend/interface.py +++ b/burpui/misc/backend/interface.py @@ -7,13 +7,10 @@ .. moduleauthor:: Ziirish """ -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser - from abc import ABCMeta, abstractmethod + from ...utils import BUIlogging +from ..._compat import ConfigParser class Dummy(object): diff --git a/burpui/server.py b/burpui/server.py index 4db5460b..de3403b1 100644 --- a/burpui/server.py +++ b/burpui/server.py @@ -7,15 +7,12 @@ .. moduleauthor:: Ziirish """ -try: - import ConfigParser -except ImportError: - import configparser as ConfigParser import traceback import sys import os from .misc.auth.handler import UserAuthHandler +from ._compat import ConfigParser from flask import Flask