error_report.py 3.93 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
'''
Faraday Penetration Test IDE
Copyright (C) 2013  Infobyte LLC (http://www.infobytesec.com/)
See the file 'doc/LICENSE' for the license information

'''
"""
This module will help us to retrieve information
about the app state and system information and
report it to developers to be able to get information about
a crash or bug
"""
import sys
import traceback
import threading
import model.guiapi
from cStringIO import StringIO
from gui.customevents import ShowExceptionCustomEvent
from gui.customevents import EXCEPTION_ID
from config.configuration import getInstanceConfiguration
import json
import time

CONF = getInstanceConfiguration()



def get_crash_log():
    pass

def get_system_info():
    pass


def exception_handler(type, value, tb):
    """
    This is a custom exception handler to replace the python original one.
    The idea is to show the user a dialog with the information and let him/her
    decide wether to send the developers a report with additional info.
    The report is created and sent using the callback.
    Since this handler may be called from threads, the dialog must be created
    using gtk idle_add or signals to avoid issues.
    """
    import hashlib
    import platform

    text = StringIO()
    traceback.print_exception(type, value, tb, file=text)
    error_name = text.getvalue().split('\n')[-2]

    excepts = """
    Traceback: %s
    """ % (text.getvalue() )

    exception_hash = hashlib.sha256(excepts).hexdigest()
    os_dist = " ".join(platform.dist())
    python_version = platform.python_version()
    faraday_version = CONF.getVersion()

    modules_info = ""
    try:
        import pip
        modules_info = ",".join([ "%s=%s" % (x.key, x.version)
                            for x in pip.get_installed_distributions()])
    except (ImportError, AttributeError):
        pass


    python_dist = "Python %s \n Modules: [ %s ]" % (python_version, modules_info)

    description = """
    Exception: %s
    Identifier: %s
    Versions: OS: %s,
              Faraday Version: %s
              Python Versions: %s
    """ % (excepts, exception_hash, os_dist, faraday_version, python_dist)



    event = ShowExceptionCustomEvent(description, reportToDevelopers, error_name)
    model.guiapi.postCustomEvent(event)
    text.seek(0)
    text.truncate()
    del text


def reportToDevelopers(name=None, *description):
    try:
        import requests
        import hashlib
        import platform

        uri = CONF.getTktPostUri()
        headers = json.loads(CONF.getApiParams())
        params = json.loads(CONF.getApiParams())

        params['description'] = description[1]

        if name is not None:
            params['summary'] = name
        else:
            params['summary'] = 'autoreport %s' % time.time()

        resp = requests.post(uri,
                            headers = headers,
                            data = params, timeout = 1, verify=True)

        model.api.devlog("Report sent to faraday server")

    except Exception as e:
        model.api.devlog("Error reporting to developers:")
        model.api.devlog(e)

def installThreadExcepthook():
    """
    Workaround for sys.excepthook thread bug from
    http://spyced.blogspot.com/2007/06/workaround-for-sysexcepthook-bug.html
    (https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470).
    Call once from __main__ before creating any threads.
    If using psyco, call psyco.cannotcompile(threading.Thread.run)
    since this replaces a new-style class method.
    """
    init_old = threading.Thread.__init__
    def init(self, *args, **kwargs):
        init_old(self, *args, **kwargs)
        run_old = self.run
        def run_with_except_hook(*args, **kw):
            try:
                run_old(*args, **kw)
            except (KeyboardInterrupt, SystemExit):
                raise
            except Exception:
                sys.excepthook(*sys.exc_info())
        self.run = run_with_except_hook
    threading.Thread.__init__ = init