This class defines methods to parse and extract information from the given DBMS banner based upon the data in XML file
| 12 | from lib.core.common import sanitizeStr |
| 13 | |
| 14 | class FingerprintHandler(ContentHandler): |
| 15 | """ |
| 16 | This class defines methods to parse and extract information from |
| 17 | the given DBMS banner based upon the data in XML file |
| 18 | """ |
| 19 | |
| 20 | def __init__(self, banner, info): |
| 21 | ContentHandler.__init__(self) |
| 22 | |
| 23 | self._banner = sanitizeStr(banner or "") |
| 24 | self._regexp = None |
| 25 | self._match = None |
| 26 | self._dbmsVersion = None |
| 27 | self._techVersion = None |
| 28 | self._info = info |
| 29 | |
| 30 | def _feedInfo(self, key, value): |
| 31 | value = sanitizeStr(value) |
| 32 | |
| 33 | if value in (None, "None", ""): |
| 34 | return |
| 35 | |
| 36 | if key == "dbmsVersion": |
| 37 | self._info[key] = value |
| 38 | else: |
| 39 | if key not in self._info: |
| 40 | self._info[key] = set() |
| 41 | |
| 42 | for _ in value.split("|"): |
| 43 | self._info[key].add(_) |
| 44 | |
| 45 | def startElement(self, name, attrs): |
| 46 | if name == "regexp": |
| 47 | self._regexp = sanitizeStr(attrs.get("value")) |
| 48 | _ = re.match(r"\A[A-Za-z0-9]+", self._regexp) # minor trick avoiding compiling of large amount of regexes |
| 49 | |
| 50 | if _ and self._banner and _.group(0).lower() in self._banner.lower() or not _: |
| 51 | self._match = re.search(self._regexp, self._banner, re.I | re.M) |
| 52 | else: |
| 53 | self._match = None |
| 54 | |
| 55 | if name == "info" and self._match: |
| 56 | self._feedInfo("type", attrs.get("type")) |
| 57 | self._feedInfo("distrib", attrs.get("distrib")) |
| 58 | self._feedInfo("release", attrs.get("release")) |
| 59 | self._feedInfo("codename", attrs.get("codename")) |
| 60 | |
| 61 | self._dbmsVersion = sanitizeStr(attrs.get("dbms_version")) |
| 62 | self._techVersion = sanitizeStr(attrs.get("tech_version")) |
| 63 | self._sp = sanitizeStr(attrs.get("sp")) |
| 64 | |
| 65 | if self._dbmsVersion and self._dbmsVersion.isdigit(): |
| 66 | self._feedInfo("dbmsVersion", self._match.group(int(self._dbmsVersion))) |
| 67 | |
| 68 | if self._techVersion and self._techVersion.isdigit(): |
| 69 | self._feedInfo("technology", "%s %s" % (attrs.get("technology"), self._match.group(int(self._techVersion)))) |
| 70 | else: |
| 71 | self._feedInfo("technology", attrs.get("technology")) |
no outgoing calls
no test coverage detected
searching dependent graphs…