mirror of
https://github.com/CCOSTAN/Home-AssistantConfig.git
synced 2025-02-22 17:06:15 +00:00
391 lines
12 KiB
Python
391 lines
12 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import nmap
|
|
import datetime
|
|
import os
|
|
|
|
from nose.tools import assert_equals
|
|
from nose.tools import raises
|
|
from nose import with_setup
|
|
|
|
from multiprocessing import Value
|
|
|
|
"""
|
|
test_nmap.py - tests cases for python-nmap
|
|
|
|
Source code : https://bitbucket.org/xael/python-nmap
|
|
|
|
Author :
|
|
|
|
* Alexandre Norman - norman at xael.org
|
|
|
|
Contributors:
|
|
|
|
* Steve 'Ashcrow' Milner - steve at gnulinux.net
|
|
* Brian Bustin - brian at bustin.us
|
|
* old.schepperhand
|
|
* Johan Lundberg
|
|
* Thomas D. maaaaz
|
|
* Robert Bost
|
|
|
|
Licence : GPL v3 or any later version
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
"""
|
|
|
|
##########################################################################################
|
|
|
|
"""
|
|
This plugin provides ``--pdb`` and ``--pdb-failures`` options. The ``--pdb``
|
|
option will drop the test runner into pdb when it encounters an error. To
|
|
drop into pdb on failure, use ``--pdb-failures``.
|
|
"""
|
|
|
|
import pdb
|
|
from nose.plugins.base import Plugin
|
|
|
|
class Pdb(Plugin):
|
|
"""
|
|
Provides --pdb and --pdb-failures options that cause the test runner to
|
|
drop into pdb if it encounters an error or failure, respectively.
|
|
"""
|
|
enabled_for_errors = False
|
|
enabled_for_failures = False
|
|
score = 5 # run last, among builtins
|
|
|
|
def options(self, parser, env):
|
|
"""Register commandline options.
|
|
"""
|
|
parser.add_option(
|
|
"--pdb", action="store_true", dest="debugBoth",
|
|
default=env.get('NOSE_PDB', False),
|
|
help="Drop into debugger on failures or errors")
|
|
parser.add_option(
|
|
"--pdb-failures", action="store_true",
|
|
dest="debugFailures",
|
|
default=env.get('NOSE_PDB_FAILURES', False),
|
|
help="Drop into debugger on failures")
|
|
parser.add_option(
|
|
"--pdb-errors", action="store_true",
|
|
dest="debugErrors",
|
|
default=env.get('NOSE_PDB_ERRORS', False),
|
|
help="Drop into debugger on errors")
|
|
|
|
def configure(self, options, conf):
|
|
"""Configure which kinds of exceptions trigger plugin.
|
|
"""
|
|
self.conf = conf
|
|
self.enabled_for_errors = options.debugErrors or options.debugBoth
|
|
self.enabled_for_failures = options.debugFailures or options.debugBoth
|
|
self.enabled = self.enabled_for_failures or self.enabled_for_errors
|
|
|
|
def addError(self, test, err):
|
|
"""Enter pdb if configured to debug errors.
|
|
"""
|
|
if not self.enabled_for_errors:
|
|
return
|
|
self.debug(err)
|
|
|
|
def addFailure(self, test, err):
|
|
"""Enter pdb if configured to debug failures.
|
|
"""
|
|
if not self.enabled_for_failures:
|
|
return
|
|
self.debug(err)
|
|
|
|
def debug(self, err):
|
|
import sys # FIXME why is this import here?
|
|
ec, ev, tb = err
|
|
stdout = sys.stdout
|
|
sys.stdout = sys.__stdout__
|
|
try:
|
|
pdb.post_mortem(tb)
|
|
finally:
|
|
sys.stdout = stdout
|
|
|
|
##########################################################################################
|
|
|
|
def setup_module():
|
|
global nm
|
|
nm = nmap.PortScanner()
|
|
|
|
|
|
@raises(nmap.PortScannerError)
|
|
def test_wrong_args():
|
|
nm.scan(arguments='-wrongargs')
|
|
|
|
|
|
def test_host_scan_error():
|
|
assert('error' in nm.scan('noserver.example.com', arguments='-sP')['nmap']['scaninfo'])
|
|
|
|
|
|
def xmlfile_read_setup():
|
|
nm.analyse_nmap_xml_scan(open('scanme_output.xml').read())
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_command_line():
|
|
try:
|
|
global NMAP_XML_VERSION
|
|
NMAP_XML_VERSION = os.environ['NMAP_XML_VERSION']
|
|
except:
|
|
raise ValueError('Set env NMAP_XML_VERSION')
|
|
|
|
assert_equals(nm.command_line(), './nmap-{0}/nmap -sV -oX scanme_output-{0}.xml scanme.nmap.org'.format(NMAP_XML_VERSION))
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_scan_info():
|
|
assert('tcp' in nm.scaninfo())
|
|
assert('method' in nm.scaninfo()['tcp'])
|
|
assert_equals('connect', nm.scaninfo()['tcp']['method'])
|
|
assert('services' in nm.scaninfo()['tcp'])
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_all_hosts():
|
|
assert_equals(['45.33.32.156'], nm.all_hosts())
|
|
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_host():
|
|
assert_equals('scanme.nmap.org', nm['45.33.32.156'].hostname())
|
|
assert({'name':'scanme.nmap.org', 'type':'user'} in nm['45.33.32.156'].hostnames())
|
|
assert_equals('up', nm['45.33.32.156'].state())
|
|
assert_equals(['tcp'], nm['45.33.32.156'].all_protocols())
|
|
|
|
def test_host_no_hostname():
|
|
# Covers bug : https://bitbucket.org/xael/python-nmap/issues/7/error-with-hostname
|
|
nm.scan('127.0.0.2')
|
|
assert_equals('', nm['127.0.0.2'].hostname())
|
|
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_port():
|
|
assert_equals([80, 9929, 22, 31337], list(nm['45.33.32.156']['tcp'].keys()))
|
|
assert(nm['45.33.32.156'].has_tcp(22))
|
|
assert(nm['45.33.32.156'].has_tcp(23) == False)
|
|
assert('conf' in list(nm['45.33.32.156']['tcp'][22]))
|
|
assert('cpe' in list(nm['45.33.32.156']['tcp'][22]))
|
|
assert('name' in list(nm['45.33.32.156']['tcp'][22]))
|
|
assert('product' in list(nm['45.33.32.156']['tcp'][22]))
|
|
assert('reason' in list(nm['45.33.32.156']['tcp'][22]))
|
|
assert('state' in list(nm['45.33.32.156']['tcp'][22]))
|
|
assert('version' in list(nm['45.33.32.156']['tcp'][22]))
|
|
|
|
assert('10' in nm['45.33.32.156']['tcp'][22]['conf'])
|
|
global NMAP_XML_VERSION
|
|
if NMAP_XML_VERSION=='6.40':
|
|
assert_equals('', nm['45.33.32.156']['tcp'][22]['cpe'])
|
|
assert_equals('', nm['45.33.32.156']['tcp'][22]['product'])
|
|
assert_equals('', nm['45.33.32.156']['tcp'][22]['version'])
|
|
else:
|
|
assert('cpe:/o:linux:linux_kernel' in nm['45.33.32.156']['tcp'][22]['cpe'])
|
|
assert('OpenSSH' in nm['45.33.32.156']['tcp'][22]['product'])
|
|
assert('6.6.1p1 Ubuntu 2ubuntu2.3' in nm['45.33.32.156']['tcp'][22]['version'])
|
|
|
|
assert('ssh' in nm['45.33.32.156']['tcp'][22]['name'])
|
|
assert('syn-ack' in nm['45.33.32.156']['tcp'][22]['reason'])
|
|
assert('open' in nm['45.33.32.156']['tcp'][22]['state'])
|
|
|
|
assert_equals(nm['45.33.32.156']['tcp'][22], nm['45.33.32.156'].tcp(22))
|
|
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_listscan():
|
|
assert_equals('1', nm.scanstats()['uphosts'])
|
|
assert_equals('0', nm.scanstats()['downhosts'])
|
|
assert_equals('1', nm.scanstats()['totalhosts'])
|
|
assert('timestr' in nm.scanstats().keys())
|
|
assert('elapsed' in nm.scanstats().keys())
|
|
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_csv_output():
|
|
assert_equals('host;hostname;hostname_type;protocol;port;name;state;product;extrainfo;reason;version;conf;cpe',
|
|
nm.csv().split('\n')[0].strip())
|
|
|
|
global NMAP_XML_VERSION
|
|
if NMAP_XML_VERSION == '6.40':
|
|
assert_equals('45.33.32.156;scanme.nmap.org;user;tcp;22;ssh;open;;protocol 2.0;syn-ack;;10;',
|
|
nm.csv().split('\n')[1].strip())
|
|
else:
|
|
assert_equals('45.33.32.156;scanme.nmap.org;user;tcp;22;ssh;open;OpenSSH;"Ubuntu Linux; protocol 2.0";syn-ack;6.6.1p1 Ubuntu 2ubuntu2.3;10;cpe:/o:linux:linux_kernel',
|
|
nm.csv().split('\n')[1].strip())
|
|
|
|
|
|
def test_listscan():
|
|
assert(0 < len(nm.listscan('192.168.1.0/30')))
|
|
assert_equals(['127.0.0.0', '127.0.0.1', '127.0.0.2', '127.0.0.3'],
|
|
nm.listscan('localhost/30'))
|
|
|
|
|
|
|
|
def test_ipv6():
|
|
if os.getuid() == 0:
|
|
r = nm.scan('127.0.0.1', arguments='-6')
|
|
else:
|
|
r = nm.scan('127.0.0.1', arguments='-6', sudo=True)
|
|
|
|
|
|
|
|
def test_ipv4_async():
|
|
global FLAG
|
|
FLAG = Value('i', 0)
|
|
nma = nmap.PortScannerAsync()
|
|
|
|
def callback_result(host, scan_result):
|
|
global FLAG
|
|
FLAG.value = 1
|
|
|
|
nma.scan(hosts='127.0.0.1',
|
|
arguments='-p 22 -Pn',
|
|
callback=callback_result)
|
|
|
|
while nma.still_scanning():
|
|
nma.wait(2)
|
|
|
|
assert_equals(FLAG.value, 1)
|
|
|
|
|
|
def test_ipv6_async():
|
|
global FLAG_ipv6
|
|
FLAG_ipv6 = Value('i', 0)
|
|
nma_ipv6 = nmap.PortScannerAsync()
|
|
|
|
def callback_result(host, scan_result):
|
|
global FLAG_ipv6
|
|
FLAG_ipv6.value = 1
|
|
|
|
nma_ipv6.scan(hosts='::1',
|
|
arguments='-6 -p 22 -Pn',
|
|
callback=callback_result)
|
|
|
|
while nma_ipv6.still_scanning():
|
|
nma_ipv6.wait(2)
|
|
|
|
assert_equals(FLAG_ipv6.value, 1)
|
|
|
|
|
|
def scan_localhost_sudo_arg_O():
|
|
lastnm = nm.get_nmap_last_output()
|
|
|
|
if len(lastnm) > 0:
|
|
try:
|
|
nm.analyse_nmap_xml_scan(lastnm)
|
|
except:
|
|
pass
|
|
else:
|
|
if nm.command_line() == 'nmap -oX - -O 127.0.0.1':
|
|
return
|
|
|
|
if os.getuid() == 0:
|
|
nm.scan('127.0.0.1', arguments='-O')
|
|
else :
|
|
nm.scan('127.0.0.1', arguments='-O', sudo=True)
|
|
|
|
|
|
@with_setup(scan_localhost_sudo_arg_O)
|
|
def test_sudo():
|
|
assert('osmatch' in nm['127.0.0.1'])
|
|
assert(len(nm['127.0.0.1']['osmatch'][0]['osclass']) > 0)
|
|
assert_equals('Linux', nm['127.0.0.1']['osmatch'][0]['osclass'][0]['vendor'])
|
|
|
|
|
|
@with_setup(scan_localhost_sudo_arg_O)
|
|
def test_parsing_osmap_osclass_and_others():
|
|
# nosetests -v -s nmap/test_nmap.py:test_parsing_osmap_osclass_and_others
|
|
assert('osmatch' in nm['127.0.0.1'])
|
|
assert_equals(nm['127.0.0.1']['osmatch'][0]['name'], 'Linux 3.7 - 3.15')
|
|
|
|
assert('accuracy' in nm['127.0.0.1']['osmatch'][0])
|
|
assert('line' in nm['127.0.0.1']['osmatch'][0])
|
|
|
|
assert('osclass' in nm['127.0.0.1']['osmatch'][0])
|
|
assert_equals(nm['127.0.0.1']['osmatch'][0]['osclass'][0]['vendor'], 'Linux')
|
|
|
|
assert('type' in nm['127.0.0.1']['osmatch'][0]['osclass'][0])
|
|
assert('osfamily' in nm['127.0.0.1']['osmatch'][0]['osclass'][0])
|
|
assert('osgen' in nm['127.0.0.1']['osmatch'][0]['osclass'][0])
|
|
assert('accuracy' in nm['127.0.0.1']['osmatch'][0]['osclass'][0])
|
|
|
|
|
|
|
|
|
|
@with_setup(scan_localhost_sudo_arg_O)
|
|
def test_all_protocols():
|
|
assert('addresses' not in nm['127.0.0.1'].all_protocols())
|
|
assert('hostnames' not in nm['127.0.0.1'].all_protocols())
|
|
assert('status' not in nm['127.0.0.1'].all_protocols())
|
|
assert('vendor' not in nm['127.0.0.1'].all_protocols())
|
|
assert('osclass' not in nm['127.0.0.1'].all_protocols())
|
|
assert('osmatch' not in nm['127.0.0.1'].all_protocols())
|
|
assert('uptime' not in nm['127.0.0.1'].all_protocols())
|
|
assert('portused' not in nm['127.0.0.1'].all_protocols())
|
|
assert('tcp' in nm['127.0.0.1'].all_protocols())
|
|
|
|
|
|
def xmlfile_read_setup_multiple_osmatch():
|
|
nm.analyse_nmap_xml_scan(open('osmatch_output.xml').read())
|
|
|
|
|
|
@with_setup(xmlfile_read_setup_multiple_osmatch)
|
|
def test_multipe_osmatch():
|
|
assert('osmatch' in nm['127.0.0.1'])
|
|
assert('portused' in nm['127.0.0.1'])
|
|
|
|
for osm in nm['127.0.0.1']['osmatch']:
|
|
assert('accuracy' in osm)
|
|
assert('line' in osm)
|
|
assert('name' in osm)
|
|
assert('osclass' in osm)
|
|
assert('accuracy' in osm['osclass'][0])
|
|
assert('cpe' in osm['osclass'][0])
|
|
assert('osfamily' in osm['osclass'][0])
|
|
assert('osgen' in osm['osclass'][0])
|
|
assert('type' in osm['osclass'][0])
|
|
assert('vendor' in osm['osclass'][0])
|
|
|
|
|
|
@with_setup(xmlfile_read_setup)
|
|
def test_convert_nmap_output_to_encoding():
|
|
a=nm.analyse_nmap_xml_scan(open('scanme_output.xml').read())
|
|
out = nmap.convert_nmap_output_to_encoding(a, code="ascii")
|
|
assert(out['scan']['45.33.32.156']['addresses']['ipv4'] == b'45.33.32.156')
|
|
|
|
# def test_host_and_port_as_unicode():
|
|
# # nosetests -x -s nmap/test_nmap.py:test_port_as_unicode
|
|
# # Covers bug : https://bitbucket.org/xael/python-nmap/issues/9/can-not-pass-ports-with-unicode-string-at
|
|
# nma = nm.scan(hosts=u'127.0.0.1', ports=u'22')
|
|
# assert_equals(nma['nmap']['scaninfo']['error'], '')
|
|
|
|
|
|
|
|
def test_WARNING_case_sensitive():
|
|
nm.scan('localhost', arguments= '-S 127.0.0.1')
|
|
assert('warning' in nm.scaninfo())
|
|
assert('WARNING' in nm.scaninfo()['warning'][0])
|
|
|
|
|
|
def test_scan_progressive():
|
|
nmp = nmap.PortScannerAsync()
|
|
|
|
def callback(host, scan_data):
|
|
assert(host is not None)
|
|
|
|
nmp.scan(hosts='127.0.0.1', arguments='-sV', callback=callback)
|
|
nmp.wait()
|
|
|