# Path: ptp/libptp/exceptions.py
# class NotSupportedVersionError(PTPError):
#     """:mod:`ptp` error when the version of the tool is not supported."""
#     pass
# 
# Path: ptp/libptp/constants.py
# UNKNOWN = 0
# 
# Path: ptp/libptp/parser.py
# class XMLParser(AbstractParser):
# 
#     """Specialized parser for XML files.
# 
#     Define the special :func:`handle_file` function in order to process the XML report file.
# 
#     """
# 
#     #: str -- XMLParser only supports XML files.
#     __format__ = 'xml'
# 
#     def __init__(self, pathname='./', filename='*.xml', **kwargs):
#         """Initialize :class:`XMLParser`."""
#         AbstractParser.__init__(self, pathname, filename, **kwargs)
# 
#     @classmethod
#     def handle_file(cls, pathname='./', filename='*.xml', first=True):
#         """Return the root node of the XML file.
# 
#         :param str pathname: Path to the report directory.
#         :param str filename: Regex matching the report file.
#         :param bool first: Stop the search as soon as a file has been matched.
# 
#         :raises IOError: when the report file cannot be found.
#         :raises TypeError: when the report file has not the right extension.
#         :raises lxml.etree.XMLSyntaxError: when Lxml cannot parse the XML file.
# 
#         :return: handle on the root node element from the XML file.
#         :rtype: :class:`lxml.etree._Element`
# 
#         """
#         fullpath = cls._recursive_find(pathname, filename, first=first)
#         if not len(fullpath):
#             raise IOError("Report matching '%s' cannot be found." % os.path.join(pathname, filename))
#         fullpath = fullpath[0]
#         if not fullpath.endswith(cls.__format__):
#             raise TypeError("This parser only supports '%s' files" % cls.__format__)
#         return etree.parse(fullpath).getroot()
# 
# Path: ptp/tools/wapiti/signatures.py
# SIGNATURES = {
#     # High ranked vulnerabilities
#     'SQL Injection': HIGH,
#     'Blind SQL Injection': HIGH,
#     'Command execution': HIGH,
#     'Cross Site Scripting': HIGH,
# 
#     # Medium ranked vulnerabilities
#     'Htaccess Bypass': MEDIUM,
#     'CRLF Injection': MEDIUM,
#     'CRLF': MEDIUM,
# 
#     # Low ranked vulnerabilities
#     'File Handling': LOW,  # a.k.a Path or Directory listing
#     'Resource consumption': LOW,  # TODO: Is this higher than LOW?
# 
#     # Informational ranked vulnerabilities
#     'Backup file': INFO,
#     'Potentially dangerous file': INFO,  # TODO: Is this higher than INFO?
#     'Internal Server Error': INFO}


import re
from lxml.etree import XMLSyntaxError
from ptp.libptp.exceptions import NotSupportedVersionError
from ptp.libptp.constants import UNKNOWN
from ptp.libptp.parser import XMLParser
from ptp.tools.wapiti.signatures import SIGNATURES
            raise NotSupportedVersionError('PTP does NOT support this version of Wapiti.')
        self.metadata = metadata
        return metadata

    def parse_report(self):
        """Parse the results of the report.

        :return: List of dicts where each one represents a discovery.
        :rtype: :class:`list`

        """
        section_vuln = self.stream.find('.//vulnerabilities')
        if section_vuln is None:
            return []
        vulns = []
        for category in section_vuln.findall('.//vulnerability'):
            entries = category.find('.//entries')
            if not len(entries):
                pass
            # Ensure that there are 'entry' sub-sections that represent the
            # actual discoveries/vulnerabilities.
            if len(entries.findall('.//entry')) and category.get('name') in SIGNATURES:
                vulns.append({
                    'name': category.get('name'),
                    'ranking': SIGNATURES.get(category.get('name'), UNKNOWN),
                    'description': category.find('.//description').text})
        self.vulns = vulns
        return vulns



# Path: ptp/libptp/exceptions.py
# class NotSupportedVersionError(PTPError):
#     """:mod:`ptp` error when the version of the tool is not supported."""
#     pass
# 
# Path: ptp/libptp/constants.py
# UNKNOWN = 0
# 
# Path: ptp/libptp/parser.py
# class XMLParser(AbstractParser):
# 
#     """Specialized parser for XML files.
# 
#     Define the special :func:`handle_file` function in order to process the XML report file.
# 
#     """
# 
#     #: str -- XMLParser only supports XML files.
#     __format__ = 'xml'
# 
#     def __init__(self, pathname='./', filename='*.xml', **kwargs):
#         """Initialize :class:`XMLParser`."""
#         AbstractParser.__init__(self, pathname, filename, **kwargs)
# 
#     @classmethod
#     def handle_file(cls, pathname='./', filename='*.xml', first=True):
#         """Return the root node of the XML file.
# 
#         :param str pathname: Path to the report directory.
#         :param str filename: Regex matching the report file.
#         :param bool first: Stop the search as soon as a file has been matched.
# 
#         :raises IOError: when the report file cannot be found.
#         :raises TypeError: when the report file has not the right extension.
#         :raises lxml.etree.XMLSyntaxError: when Lxml cannot parse the XML file.
# 
#         :return: handle on the root node element from the XML file.
#         :rtype: :class:`lxml.etree._Element`
# 
#         """
#         fullpath = cls._recursive_find(pathname, filename, first=first)
#         if not len(fullpath):
#             raise IOError("Report matching '%s' cannot be found." % os.path.join(pathname, filename))
#         fullpath = fullpath[0]
#         if not fullpath.endswith(cls.__format__):
#             raise TypeError("This parser only supports '%s' files" % cls.__format__)
#         return etree.parse(fullpath).getroot()
# 
# Path: ptp/tools/wapiti/signatures.py
# SIGNATURES = {
#     # High ranked vulnerabilities
#     'SQL Injection': HIGH,
#     'Blind SQL Injection': HIGH,
#     'Command execution': HIGH,
#     'Cross Site Scripting': HIGH,
# 
#     # Medium ranked vulnerabilities
#     'Htaccess Bypass': MEDIUM,
#     'CRLF Injection': MEDIUM,
#     'CRLF': MEDIUM,
# 
#     # Low ranked vulnerabilities
#     'File Handling': LOW,  # a.k.a Path or Directory listing
#     'Resource consumption': LOW,  # TODO: Is this higher than LOW?
# 
#     # Informational ranked vulnerabilities
#     'Backup file': INFO,
#     'Potentially dangerous file': INFO,  # TODO: Is this higher than INFO?
#     'Internal Server Error': INFO}


# Path: ptp/tools/wapiti/parser.py
import re
from lxml.etree import XMLSyntaxError
from ptp.libptp.exceptions import NotSupportedVersionError
from ptp.libptp.constants import UNKNOWN
from ptp.libptp.parser import XMLParser
from ptp.tools.wapiti.signatures import SIGNATURES

            raise NotSupportedVersionError('PTP does NOT support this version of Wapiti.')
        self.metadata = metadata
        return metadata

    def parse_report(self):
        """Parse the results of the report.

        :return: List of dicts where each one represents a discovery.
        :rtype: :class:`list`

        """
        section_vuln = self.stream.find('.//vulnerabilities')
        if section_vuln is None:
            return []
        vulns = []
        for category in section_vuln.findall('.//vulnerability'):
            entries = category.find('.//entries')
            if not len(entries):
                pass
            # Ensure that there are 'entry' sub-sections that represent the
            # actual discoveries/vulnerabilities.
            if len(entries.findall('.//entry')) and category.get('name') in SIGNATURES:
                vulns.append({
                    'name': category.get('name'),
                    'ranking': SIGNATURES.get(category.get('name'), UNKNOWN),
                    'description': category.find('.//description').text})
        self.vulns = vulns
        return vulns



class Wapiti221XMLParser(XMLParser):