diff --git a/.travis.yml b/.travis.yml index 7030496..9e7dd94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ install: - "pip install flake8" - "pip install defusedxml" - "pip install pytest" + - "pip install pytest-cov" # - "pip install boto" # disabled: since boto not supporting py3 # - "pip install pymongo sqlalchemy MySQL-python" # disabled MySQL-python (not py3 compatible) # - "pip install pymongo sqlalchemy pymysql" @@ -26,7 +27,7 @@ install: before_script: - "flake8 . --exclude test,docs,examples" # - mysql -e 'create database poulet;' -script: pytest --ignore=libnmap/test/test_backend_plugin_factory.py . +script: pytest --cov=libnmap/ --ignore=libnmap/test/test_backend_plugin_factory.py . after_success: coveralls deploy: diff --git a/docs/conf.py b/docs/conf.py index 712cc25..07e9dc8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -11,7 +11,8 @@ # All configuration values have a default; values that are commented out # serve to show the default. -import sys, os +import os +import sys # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -184,7 +185,13 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ("index", "libnmap.tex", u"libnmap Documentation", u"Ronald Bister", "manual") + ( + "index", + "libnmap.tex", + u"libnmap Documentation", + u"Ronald Bister", + "manual", + ) ] # The name of an image file (relative to this directory) to place at the top of @@ -212,7 +219,9 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [("index", "libnmap", u"libnmap Documentation", [u"Ronald Bister"], 1)] +man_pages = [ + ("index", "libnmap", u"libnmap Documentation", [u"Ronald Bister"], 1) +] # If true, show URL addresses after external links. # man_show_urls = False diff --git a/examples/elastikibana.py b/examples/elastikibana.py index f91cadc..3be6487 100644 --- a/examples/elastikibana.py +++ b/examples/elastikibana.py @@ -1,10 +1,12 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from libnmap.parser import NmapParser -from elasticsearch import Elasticsearch from datetime import datetime + import pygeoip +from elasticsearch import Elasticsearch + +from libnmap.parser import NmapParser def store_report(nmap_report, database, index): diff --git a/examples/es_plugin.py b/examples/es_plugin.py index 4bf2cbe..6474399 100644 --- a/examples/es_plugin.py +++ b/examples/es_plugin.py @@ -1,10 +1,11 @@ #!/usr/bin/env python +import json +from datetime import datetime + from libnmap.parser import NmapParser -from libnmap.reportjson import ReportDecoder from libnmap.plugins.es import NmapElasticsearchPlugin -from datetime import datetime -import json +from libnmap.reportjson import ReportDecoder nmap_report = NmapParser.parse_fromfile("libnmap/test/files/1_hosts.xml") mindex = datetime.fromtimestamp(nmap_report.started).strftime("%Y-%m-%d") diff --git a/examples/json_serialize.py b/examples/json_serialize.py index 4e70b16..b7d5148 100644 --- a/examples/json_serialize.py +++ b/examples/json_serialize.py @@ -1,9 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import json + from libnmap.parser import NmapParser from libnmap.reportjson import ReportDecoder, ReportEncoder -import json nmap_report_obj = NmapParser.parse_fromfile("libnmap/test/files/1_hosts.xml") diff --git a/examples/proc_async.py b/examples/proc_async.py index 868f808..01c167c 100644 --- a/examples/proc_async.py +++ b/examples/proc_async.py @@ -1,9 +1,9 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from libnmap.process import NmapProcess from time import sleep +from libnmap.process import NmapProcess nmap_proc = NmapProcess(targets="scanme.nmap.org", options="-sT") nmap_proc.run_background() diff --git a/examples/proc_nmap_like.py b/examples/proc_nmap_like.py index bd85cfd..bed93fe 100644 --- a/examples/proc_nmap_like.py +++ b/examples/proc_nmap_like.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from libnmap.process import NmapProcess from libnmap.parser import NmapParser, NmapParserException +from libnmap.process import NmapProcess # start a new nmap scan on localhost with some specific options diff --git a/libnmap/diff.py b/libnmap/diff.py index d2e8e34..432aa2f 100644 --- a/libnmap/diff.py +++ b/libnmap/diff.py @@ -3,11 +3,11 @@ class DictDiffer(object): """ - Calculate the difference between two dictionaries as: - (1) items added - (2) items removed - (3) keys same in both but changed values - (4) keys same in both and unchanged values + Calculate the difference between two dictionaries as: + (1) items added + (2) items removed + (3) keys same in both but changed values + (4) keys same in both and unchanged values """ def __init__(self, current_dict, past_dict): @@ -40,35 +40,35 @@ def unchanged(self): class NmapDiff(DictDiffer): """ - NmapDiff compares two objects of same type to enable the user to check: - - - what has changed - - what has been added - - what has been removed - - what was kept unchanged - - NmapDiff inherit from DictDiffer which makes the actual comparaison. - The different methods from DictDiffer used by NmapDiff are the - following: - - - NmapDiff.changed() - - NmapDiff.added() - - NmapDiff.removed() - - NmapDiff.unchanged() - - Each of the returns a python set() of key which have changed in the - compared objects. To check the different keys that could be returned, - refer to the get_dict() method of the objects you which to - compare (i.e: libnmap.objects.NmapHost, NmapService,...). + NmapDiff compares two objects of same type to enable the user to check: + + - what has changed + - what has been added + - what has been removed + - what was kept unchanged + + NmapDiff inherit from DictDiffer which makes the actual comparaison. + The different methods from DictDiffer used by NmapDiff are the + following: + + - NmapDiff.changed() + - NmapDiff.added() + - NmapDiff.removed() + - NmapDiff.unchanged() + + Each of the returns a python set() of key which have changed in the + compared objects. To check the different keys that could be returned, + refer to the get_dict() method of the objects you which to + compare (i.e: libnmap.objects.NmapHost, NmapService,...). """ def __init__(self, nmap_obj1, nmap_obj2): """ - Constructor of NmapDiff: + Constructor of NmapDiff: - - Checks if the two objects are of the same class - - Checks if the objects are "comparable" via a call to id() (dirty) - - Inherits from DictDiffer and + - Checks if the two objects are of the same class + - Checks if the objects are "comparable" via a call to id() (dirty) + - Inherits from DictDiffer and """ if ( nmap_obj1.__class__ != nmap_obj2.__class__ diff --git a/libnmap/objects/__init__.py b/libnmap/objects/__init__.py index b7f24e4..ddf3699 100644 --- a/libnmap/objects/__init__.py +++ b/libnmap/objects/__init__.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- -from libnmap.objects.report import NmapReport from libnmap.objects.host import NmapHost +from libnmap.objects.report import NmapReport from libnmap.objects.service import NmapService __all__ = ["NmapReport", "NmapHost", "NmapService"] diff --git a/libnmap/objects/cpe.py b/libnmap/objects/cpe.py index 8b6e497..9476444 100644 --- a/libnmap/objects/cpe.py +++ b/libnmap/objects/cpe.py @@ -3,11 +3,11 @@ class CPE(object): """ - CPE class offers an API for basic CPE objects. - These objects could be found in NmapService or in tag - within NmapHost. + CPE class offers an API for basic CPE objects. + These objects could be found in NmapService or in tag + within NmapHost. - :todo: interpret CPE string and provide appropriate API + :todo: interpret CPE string and provide appropriate API """ def __init__(self, cpestring): @@ -29,14 +29,14 @@ def __init__(self, cpestring): @property def cpestring(self): """ - Accessor for the full CPE string. + Accessor for the full CPE string. """ return self._cpestring @property def cpedict(self): """ - Accessor for _cpedict + Accessor for _cpedict """ return self._cpedict @@ -45,60 +45,60 @@ def __repr__(self): def get_part(self): """ - Returns the cpe part (/o, /h, /a) + Returns the cpe part (/o, /h, /a) """ return self._cpedict["part"] def get_vendor(self): """ - Returns the vendor name + Returns the vendor name """ return self._cpedict["vendor"] def get_product(self): """ - Returns the product name + Returns the product name """ return self._cpedict["product"] def get_version(self): """ - Returns the version of the cpe + Returns the version of the cpe """ return self._cpedict["version"] def get_update(self): """ - Returns the update version + Returns the update version """ return self._cpedict["update"] def get_edition(self): """ - Returns the cpe edition + Returns the cpe edition """ return self._cpedict["edition"] def get_language(self): """ - Returns the cpe language + Returns the cpe language """ return self._cpedict["language"] def is_application(self): """ - Returns True if cpe describes an application + Returns True if cpe describes an application """ return self.get_part() == "/a" def is_hardware(self): """ - Returns True if cpe describes a hardware + Returns True if cpe describes a hardware """ return self.get_part() == "/h" def is_operating_system(self): """ - Returns True if cpe describes an operating system + Returns True if cpe describes an operating system """ return self.get_part() == "/o" diff --git a/libnmap/objects/host.py b/libnmap/objects/host.py index 980682f..a8e1ba6 100644 --- a/libnmap/objects/host.py +++ b/libnmap/objects/host.py @@ -6,7 +6,7 @@ class NmapHost(object): """ - NmapHost is a class representing a host object of NmapReport + NmapHost is a class representing a host object of NmapReport """ def __init__( @@ -20,17 +20,17 @@ def __init__( extras=None, ): """ - NmapHost constructor - :param starttime: unix timestamp of when the scan against - that host started - :type starttime: string - :param endtime: unix timestamp of when the scan against - that host ended - :type endtime: string - :param address: dict ie :{'addr': '127.0.0.1', 'addrtype': 'ipv4'} - :param status: dict ie:{'reason': 'localhost-response', - 'state': 'up'} - :return: NmapHost: + NmapHost constructor + :param starttime: unix timestamp of when the scan against + that host started + :type starttime: string + :param endtime: unix timestamp of when the scan against + that host ended + :type endtime: string + :param address: dict ie :{'addr': '127.0.0.1', 'addrtype': 'ipv4'} + :param status: dict ie:{'reason': 'localhost-response', + 'state': 'up'} + :return: NmapHost: """ self._starttime = starttime self._endtime = endtime @@ -65,13 +65,13 @@ def __init__( def __eq__(self, other): """ - Compare eq NmapHost based on : + Compare eq NmapHost based on : - - hostnames - - address - - if an associated services has changed + - hostnames + - address + - if an associated services has changed - :return: boolean + :return: boolean """ rval = False if self.__class__ == other.__class__ and self.id == other.id: @@ -80,13 +80,13 @@ def __eq__(self, other): def __ne__(self, other): """ - Compare ne NmapHost based on: + Compare ne NmapHost based on: - - hostnames - - address - - if an associated services has changed + - hostnames + - address + - if an associated services has changed - :return: boolean + :return: boolean """ rval = True if self.__class__ == other.__class__ and self.id == other.id: @@ -95,8 +95,8 @@ def __ne__(self, other): def __repr__(self): """ - String representing the object - :return: string + String representing the object + :return: string """ return "{0}: [{1} ({2}) - {3}]".format( self.__class__.__name__, @@ -107,8 +107,8 @@ def __repr__(self): def __hash__(self): """ - Hash is needed to be able to use our object in sets - :return: hash + Hash is needed to be able to use our object in sets + :return: hash """ return ( hash(self.status) @@ -119,46 +119,46 @@ def __hash__(self): def changed(self, other): """ - return the number of attribute who have changed - :param other: NmapHost object to compare - :return int + return the number of attribute who have changed + :param other: NmapHost object to compare + :return int """ return len(self.diff(other).changed()) @property def starttime(self): """ - Accessor for the unix timestamp of when the scan was started + Accessor for the unix timestamp of when the scan was started - :return: string + :return: string """ return self._starttime @property def endtime(self): """ - Accessor for the unix timestamp of when the scan ended + Accessor for the unix timestamp of when the scan ended - :return: string + :return: string """ return self._endtime @property def address(self): """ - Accessor for the IP address of the scanned host + Accessor for the IP address of the scanned host - :return: IP address as a string + :return: IP address as a string """ return self._main_address @address.setter def address(self, addrdict): """ - Setter for the address dictionnary. + Setter for the address dictionnary. - :param addrdict: valid dict is {'addr': '1.1.1.1', - 'addrtype': 'ipv4'} + :param addrdict: valid dict is {'addr': '1.1.1.1', + 'addrtype': 'ipv4'} """ if addrdict["addrtype"] == "ipv4": self._ipv4_addr = addrdict["addr"] @@ -175,65 +175,65 @@ def address(self, addrdict): @property def ipv4(self): """ - Accessor for the IPv4 address of the scanned host + Accessor for the IPv4 address of the scanned host - :return: IPv4 address as a string + :return: IPv4 address as a string """ return self._ipv4_addr or "" @property def mac(self): """ - Accessor for the MAC address of the scanned host + Accessor for the MAC address of the scanned host - :return: MAC address as a string + :return: MAC address as a string """ return self._mac_addr or "" @property def vendor(self): """ - Accessor for the vendor attribute of the scanned host + Accessor for the vendor attribute of the scanned host - :return: string (vendor) of empty string if no vendor defined + :return: string (vendor) of empty string if no vendor defined """ return self._vendor or "" @property def ipv6(self): """ - Accessor for the IPv6 address of the scanned host + Accessor for the IPv6 address of the scanned host - :return: IPv6 address as a string + :return: IPv6 address as a string """ return self._ipv6_addr or "" @property def status(self): """ - Accessor for the host's status (up, down, unknown...) + Accessor for the host's status (up, down, unknown...) - :return: string + :return: string """ return self._status["state"] @status.setter def status(self, statusdict): """ - Setter for the status dictionnary. + Setter for the status dictionnary. - :param statusdict: valid dict is {"state": "open", - "reason": "syn-ack", - "reason_ttl": "0"} - 'state' is the only mandatory key. + :param statusdict: valid dict is {"state": "open", + "reason": "syn-ack", + "reason_ttl": "0"} + 'state' is the only mandatory key. """ self._status = statusdict def is_up(self): """ - method to determine if host is up or not + method to determine if host is up or not - :return: bool + :return: bool """ rval = False if self.status == "up": @@ -243,36 +243,36 @@ def is_up(self): @property def hostnames(self): """ - Accessor returning the list of hostnames (array of strings). + Accessor returning the list of hostnames (array of strings). - :return: array of string + :return: array of string """ return self._hostnames @property def services(self): """ - Accessor for the array of scanned services for that host. + Accessor for the array of scanned services for that host. - An array of NmapService objects is returned. + An array of NmapService objects is returned. - :return: array of NmapService + :return: array of NmapService """ return self._services def get_ports(self): """ - Retrieve a list of the port used by each service of the NmapHost + Retrieve a list of the port used by each service of the NmapHost - :return: list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')] + :return: list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')] """ return [(p.port, p.protocol) for p in self._services] def get_open_ports(self): """ - Same as get_ports() but only for open ports + Same as get_ports() but only for open ports - :return: list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')] + :return: list: of tuples (port,'proto') ie:[(22,'tcp'),(25, 'tcp')] """ return [ (p.port, p.protocol) for p in self._services if p.state == "open" @@ -280,10 +280,10 @@ def get_open_ports(self): def get_service(self, portno, protocol="tcp"): """ - :param portno: int the portnumber - :param protocol='tcp': string ('tcp','udp') + :param portno: int the portnumber + :param protocol='tcp': string ('tcp','udp') - :return: NmapService or None + :return: NmapService or None """ plist = [ p @@ -296,9 +296,9 @@ def get_service(self, portno, protocol="tcp"): def get_service_byid(self, service_id): """ - Returns a NmapService by providing its id. + Returns a NmapService by providing its id. - The id of a nmap service is a python tupl made of (protocol, port) + The id of a nmap service is a python tupl made of (protocol, port) """ rval = None for _tmpservice in self._services: @@ -308,10 +308,10 @@ def get_service_byid(self, service_id): def os_class_probabilities(self): """ - Returns an array of possible OS class detected during - the OS fingerprinting. + Returns an array of possible OS class detected during + the OS fingerprinting. - :return: Array of NmapOSClass objects + :return: Array of NmapOSClass objects """ rval = [] if self.os is not None: @@ -320,10 +320,10 @@ def os_class_probabilities(self): def os_match_probabilities(self): """ - Returns an array of possible OS match detected during - the OS fingerprinting + Returns an array of possible OS match detected during + the OS fingerprinting - :return: array of NmapOSMatches objects + :return: array of NmapOSMatches objects """ rval = [] if self.os is not None: @@ -333,18 +333,18 @@ def os_match_probabilities(self): @property def os_fingerprinted(self): """ - Specify if the host has OS fingerprint data available + Specify if the host has OS fingerprint data available - :return: Boolean + :return: Boolean """ return self._osfingerprinted @property def os_fingerprint(self): """ - Returns the fingerprint of the scanned system. + Returns the fingerprint of the scanned system. - :return: string + :return: string """ rval = "" if self.os is not None: @@ -353,11 +353,11 @@ def os_fingerprint(self): def os_ports_used(self): """ - Returns an array of the ports used for OS fingerprinting + Returns an array of the ports used for OS fingerprinting - :return: array of ports used: [{'portid': '22', - 'proto': 'tcp', - 'state': 'open'},] + :return: array of ports used: [{'portid': '22', + 'proto': 'tcp', + 'state': 'open'},] """ rval = [] try: @@ -369,10 +369,10 @@ def os_ports_used(self): @property def tcpsequence(self): """ - Returns the difficulty to determine remotely predict - the tcp sequencing. + Returns the difficulty to determine remotely predict + the tcp sequencing. - return: string + return: string """ rval = "" try: @@ -384,9 +384,9 @@ def tcpsequence(self): @property def ipsequence(self): """ - Return the class of ip sequence of the remote hosts. + Return the class of ip sequence of the remote hosts. - :return: string + :return: string """ rval = "" try: @@ -398,9 +398,9 @@ def ipsequence(self): @property def uptime(self): """ - uptime of the remote host (if nmap was able to determine it) + uptime of the remote host (if nmap was able to determine it) - :return: string (in seconds) + :return: string (in seconds) """ rval = 0 try: @@ -412,9 +412,9 @@ def uptime(self): @property def lastboot(self): """ - Since when the host was booted. + Since when the host was booted. - :return: string + :return: string """ rval = "" try: @@ -426,9 +426,9 @@ def lastboot(self): @property def distance(self): """ - Number of hops to host + Number of hops to host - :return: int + :return: int """ rval = 0 try: @@ -440,9 +440,9 @@ def distance(self): @property def scripts_results(self): """ - Scripts results specific to the scanned host + Scripts results specific to the scanned host - :return: array of