Ejemplo n.º 1
0
class TestNVTICache(TestCase):
    @patch('ospd_openvas.db.MainDB')
    def setUp(self, MockMainDB):  # pylint: disable=arguments-differ
        self.db = MockMainDB()
        self.nvti = NVTICache(self.db)
        self.nvti._ctx = 'foo'

    def test_set_index(self, MockOpenvasDB):
        self.nvti._nvti_cache_name = '20.4'
        self.nvti._ctx = None

        MockOpenvasDB.find_database_by_pattern.return_value = ('foo', 22)

        ctx = self.nvti.ctx

        self.assertIsNotNone(ctx)
        self.assertEqual(ctx, 'foo')
        self.assertEqual(self.nvti.index, 22)

    def test_get_feed_version(self, MockOpenvasDB):
        self.nvti._nvti_cache_name = '20.4'

        MockOpenvasDB.get_single_item.return_value = '1234'

        resp = self.nvti.get_feed_version()

        self.assertEqual(resp, '1234')
        MockOpenvasDB.get_single_item.assert_called_with('foo', '20.4')

    def test_get_feed_version_not_available(self, MockOpenvasDB):
        pmock = PropertyMock(return_value=123)
        type(self.db).max_database_index = pmock
        self.nvti._nvti_cache_name = '20.4'
        self.nvti._ctx = None

        MockOpenvasDB.find_database_by_pattern.return_value = (None, None)

        resp = self.nvti.get_feed_version()

        self.assertIsNone(resp)
        MockOpenvasDB.find_database_by_pattern.assert_called_with('20.4', 123)

    def test_get_oids(self, MockOpenvasDB):
        MockOpenvasDB.get_filenames_and_oids.return_value = ['oids']

        resp = self.nvti.get_oids()

        self.assertEqual(resp, ['oids'])

    def test_parse_metadata_tag_missing_value(self, MockOpenvasDB):
        logging.Logger.error = Mock()

        tags = 'tag1'
        ret = NVTICache._parse_metadata_tags(  # pylint: disable=protected-access
            tags, '1.2.3')

        self.assertEqual(ret, {})
        assert_called(logging.Logger.error)

    def test_parse_metadata_tag(self, MockOpenvasDB):
        tags = 'tag1=value1'
        ret = NVTICache._parse_metadata_tags(  # pylint: disable=protected-access
            tags, '1.2.3')

        self.assertEqual(ret, {'tag1': 'value1'})

    def test_parse_metadata_tags(self, MockOpenvasDB):
        tags = 'tag1=value1|foo=bar'
        ret = NVTICache._parse_metadata_tags(  # pylint: disable=protected-access
            tags, '1.2.3')

        self.assertEqual(ret, {'tag1': 'value1', 'foo': 'bar'})

    def test_get_nvt_params(self, MockOpenvasDB):
        prefs1 = ['1|||dns-fuzz.timelimit|||entry|||default']
        prefs2 = ['1|||dns-fuzz.timelimit|||entry|||']
        prefs3 = ['1|||dns-fuzz.timelimit|||entry']

        timeout = '300'
        out_dict1 = {
            '1': {
                'id': '1',
                'type': 'entry',
                'default': 'default',
                'name': 'dns-fuzz.timelimit',
                'description': 'Description',
            },
            '0': {
                'type': 'entry',
                'id': '0',
                'default': '300',
                'name': 'timeout',
                'description': 'Script Timeout',
            },
        }

        out_dict2 = {
            '1': {
                'id': '1',
                'type': 'entry',
                'default': '',
                'name': 'dns-fuzz.timelimit',
                'description': 'Description',
            },
            '0': {
                'type': 'entry',
                'id': '0',
                'default': '300',
                'name': 'timeout',
                'description': 'Script Timeout',
            },
        }

        MockOpenvasDB.get_list_item.return_value = prefs1
        MockOpenvasDB.get_single_item.return_value = timeout

        resp = self.nvti.get_nvt_params('1.2.3.4')
        self.assertEqual(resp, out_dict1)

        MockOpenvasDB.get_list_item.return_value = prefs2

        resp = self.nvti.get_nvt_params('1.2.3.4')
        self.assertEqual(resp, out_dict2)

        MockOpenvasDB.get_list_item.return_value = prefs3

        resp = self.nvti.get_nvt_params('1.2.3.4')
        self.assertEqual(resp, out_dict2)

    def test_get_nvt_params_timeout_none(self, MockOpenvasDB):
        prefs = ['1|||dns-fuzz.timelimit|||entry|||default']
        timeout = None

        MockOpenvasDB.get_single_item.return_value = timeout
        MockOpenvasDB.get_list_item.return_value = prefs

        resp = self.nvti.get_nvt_params('1.2.3.4')
        self.assertIsNone(resp)

    def test_get_nvt_metadata(self, MockOpenvasDB):
        metadata = [
            'mantis_detect.nasl',
            '',
            '',
            'Settings/disable_cgi_scanning',
            '',
            'Services/www, 80',
            'find_service.nasl, http_version.nasl',
            'cvss_base_vector=AV:N/AC:L/Au:N/C:N/I:N'
            '/A:N|last_modification=1533906565'
            '|creation_date=1237458156'
            '|summary=Detects the ins'
            'talled version of\n  Mantis a free popular web-based '
            'bugtracking system.\n\n  This script sends HTTP GET r'
            'equest and try to get the version from the\n  respons'
            'e, and sets the result in KB.|qod_type=remote_banner',
            '',
            '',
            'URL:http://www.mantisbt.org/',
            '3',
            '0',
            'Product detection',
            'Mantis Detection',
        ]

        custom = {
            'category':
            '3',
            'creation_date':
            '1237458156',
            'cvss_base_vector':
            'AV:N/AC:L/Au:N/C:N/I:N/A:N',
            'dependencies':
            'find_service.nasl, http_version.nasl',
            'excluded_keys':
            'Settings/disable_cgi_scanning',
            'family':
            'Product detection',
            'filename':
            'mantis_detect.nasl',
            'last_modification': ('1533906565'),
            'name':
            'Mantis Detection',
            'qod_type':
            'remote_banner',
            'required_ports':
            'Services/www, 80',
            'summary': ('Detects the installed version of\n  Mantis a '
                        'free popular web-based bugtracking system.\n'
                        '\n  This script sends HTTP GET request and t'
                        'ry to get the version from the\n  response, '
                        'and sets the result in KB.'),
            'timeout':
            '0',
        }

        MockOpenvasDB.get_list_item.return_value = metadata

        resp = self.nvti.get_nvt_metadata('1.2.3.4')
        self.assertEqual(resp, custom)

    def test_get_nvt_metadata_fail(self, MockOpenvasDB):
        MockOpenvasDB.get_list_item.return_value = []

        resp = self.nvti.get_nvt_metadata('1.2.3.4')

        self.assertIsNone(resp)

    def test_get_nvt_refs(self, MockOpenvasDB):
        refs = ['', '', 'URL:http://www.mantisbt.org/']
        out_dict = {
            'cve': [''],
            'bid': [''],
            'xref': ['URL:http://www.mantisbt.org/'],
        }

        MockOpenvasDB.get_list_item.return_value = refs

        resp = self.nvti.get_nvt_refs('1.2.3.4')

        self.assertEqual(resp, out_dict)

    def test_get_nvt_refs_fail(self, MockOpenvasDB):
        MockOpenvasDB.get_list_item.return_value = []

        resp = self.nvti.get_nvt_refs('1.2.3.4')

        self.assertIsNone(resp)

    def test_get_nvt_prefs(self, MockOpenvasDB):
        prefs = ['dns-fuzz.timelimit|||entry|||default']

        MockOpenvasDB.get_list_item.return_value = prefs

        resp = self.nvti.get_nvt_prefs('1.2.3.4')

        self.assertEqual(resp, prefs)

    def test_get_nvt_timeout(self, MockOpenvasDB):
        MockOpenvasDB.get_single_item.return_value = '300'

        resp = self.nvti.get_nvt_timeout('1.2.3.4')

        self.assertEqual(resp, '300')

    def test_get_nvt_tags(self, MockOpenvasDB):
        tag = ('last_modification=1533906565'
               '|creation_date=1517443741|cvss_bas'
               'e_vector=AV:N/AC:L/Au:N/C:P/I:P/A:P|solution_type=V'
               'endorFix|qod_type=package|affected=rubygems on Debi'
               'an Linux|solution_method=DebianAPTUpgrade')

        out_dict = {
            'last_modification': '1533906565',
            'creation_date': '1517443741',
            'cvss_base_vector': 'AV:N/AC:L/Au:N/C:P/I:P/A:P',
            'solution_type': 'VendorFix',
            'qod_type': 'package',
            'affected': 'rubygems on Debian Linux',
            'solution_method': 'DebianAPTUpgrade',
        }

        MockOpenvasDB.get_single_item.return_value = tag

        resp = self.nvti.get_nvt_tags('1.2.3.4')

        self.assertEqual(out_dict, resp)

    @patch('ospd_openvas.nvticache.Openvas.get_gvm_libs_version')
    def test_set_nvti_cache_name(self, mock_version, MockOpenvasDB):
        self.assertIsNone(self.nvti._nvti_cache_name)

        mock_version.return_value = '20.10'
        self.nvti._set_nvti_cache_name()

        self.assertTrue(mock_version.called)
        self.assertEqual(self.nvti._nvti_cache_name, 'nvticache20.10')

        mock_version.reset_mock()
        mock_version.return_value = '10.0.1'

        with self.assertRaises(OspdOpenvasError):
            self.nvti._set_nvti_cache_name()

        self.assertTrue(mock_version.called)

    @patch('ospd_openvas.nvticache.Openvas.get_gvm_libs_version')
    def test_set_nvti_cache_name_raise_error(self, mock_version: Mock,
                                             MockOpenvasDB: Mock):
        mock_version.return_value = None

        with self.assertRaises(OspdOpenvasError):
            self.nvti._set_nvti_cache_name()

    @patch('ospd_openvas.nvticache.Openvas.get_gvm_libs_version')
    def test_set_nvti_cache_name_old_version(self, mock_version: Mock,
                                             MockOpenvasDB: Mock):
        mock_version.return_value = '7.0.0'

        with self.assertRaises(OspdOpenvasError):
            self.nvti._set_nvti_cache_name()

    @patch('ospd_openvas.nvticache.Openvas.get_gvm_libs_version')
    def test_get_nvti_cache_name(self, mock_version, MockOpenvasDB):
        self.assertIsNone(self.nvti._nvti_cache_name)

        mock_version.return_value = '20.4'

        self.assertEqual(self.nvti._get_nvti_cache_name(), 'nvticache20.4')
        self.assertTrue(mock_version.called)

        mock_version.reset_mock()
        mock_version.return_value = '20.10'

        self.assertEqual(self.nvti._get_nvti_cache_name(), 'nvticache20.4')
        self.assertFalse(mock_version.called)

    def test_is_compatible_version(self, MockOpenvasDB):
        self.assertFalse(self.nvti._is_compatible_version("1.0.0"))
        self.assertFalse(self.nvti._is_compatible_version("10.0.0"))
        self.assertTrue(self.nvti._is_compatible_version("11.0.1"))
        self.assertTrue(self.nvti._is_compatible_version("20.4"))
        self.assertTrue(self.nvti._is_compatible_version("20.4.2"))
        self.assertTrue(self.nvti._is_compatible_version("20.04"))
        self.assertTrue(self.nvti._is_compatible_version("20.10"))

    def test_get_nvt_files_count(self, MockOpenvasDB):
        MockOpenvasDB.get_key_count.return_value = 20

        self.assertEqual(self.nvti.get_nvt_files_count(), 20)
        MockOpenvasDB.get_key_count.assert_called_with('foo', 'filename:*')

    def test_get_nvt_count(self, MockOpenvasDB):
        MockOpenvasDB.get_key_count.return_value = 20

        self.assertEqual(self.nvti.get_nvt_count(), 20)
        MockOpenvasDB.get_key_count.assert_called_with('foo', 'nvt:*')

    def test_force_reload(self, _MockOpenvasDB):
        self.nvti.force_reload()

        self.db.release_database.assert_called_with(self.nvti)

    def test_flush(self, _MockOpenvasDB):
        self.nvti._ctx = Mock()

        self.nvti.flush()

        self.nvti._ctx.flushdb.assert_called_with()
Ejemplo n.º 2
0
class TestNVTICache(TestCase):
    def setUp(self):
        self.db = OpenvasDB()
        self.nvti = NVTICache(self.db)

    def test_get_feed_version(self, mock_redis):
        self.nvti._nvti_cache_name = '20.4'

        with patch.object(OpenvasDB, 'db_find', return_value=mock_redis):
            with patch.object(OpenvasDB,
                              'get_single_item',
                              return_value='1234'):
                resp = self.nvti.get_feed_version()
        self.assertEqual(resp, '1234')

    def test_get_oids(self, mock_redis):
        with patch.object(OpenvasDB,
                          'get_elem_pattern_by_index',
                          return_value=['oids']):
            resp = self.nvti.get_oids()
        self.assertEqual(resp, ['oids'])

    def test_parse_metadata_tags(self, mock_redis):
        tags = 'tag1'
        ret = self.nvti._parse_metadata_tags(  # pylint: disable=protected-access
            tags, '1.2.3')
        self.assertEqual(ret, {})

    def test_get_nvt_params(self, mock_redis):
        prefs = ['1|||dns-fuzz.timelimit|||entry|||default']
        prefs1 = ['1|||dns-fuzz.timelimit|||entry|||']

        timeout = '300'
        out_dict = {
            '1': {
                'id': '1',
                'type': 'entry',
                'default': 'default',
                'name': 'dns-fuzz.timelimit',
                'description': 'Description',
            },
            '0': {
                'type': 'entry',
                'id': '0',
                'default': '300',
                'name': 'timeout',
                'description': 'Script Timeout',
            },
        }

        out_dict1 = {
            '1': {
                'id': '1',
                'type': 'entry',
                'default': '',
                'name': 'dns-fuzz.timelimit',
                'description': 'Description',
            },
            '0': {
                'type': 'entry',
                'id': '0',
                'default': '300',
                'name': 'timeout',
                'description': 'Script Timeout',
            },
        }
        with patch.object(OpenvasDB, 'get_kb_context',
                          return_value=mock_redis):
            with patch.object(NVTICache,
                              'get_nvt_timeout',
                              return_value=timeout):
                with patch.object(NVTICache,
                                  'get_nvt_prefs',
                                  return_value=prefs):

                    resp = self.nvti.get_nvt_params('1.2.3.4')

                with patch.object(NVTICache,
                                  'get_nvt_prefs',
                                  return_value=prefs1):

                    resp1 = self.nvti.get_nvt_params('1.2.3.4')
        self.assertEqual(resp, out_dict)
        self.assertEqual(resp1, out_dict1)

    @patch('ospd_openvas.db.subprocess')
    def test_get_nvt_metadata(self, mock_subps, mock_redis):
        metadata = [
            'mantis_detect.nasl',
            '',
            '',
            'Settings/disable_cgi_scanning',
            '',
            'Services/www, 80',
            'find_service.nasl, http_version.nasl',
            'cvss_base_vector=AV:N/AC:L/Au:N/C:N/I:N'
            '/A:N|last_modification=1533906565'
            '|creation_date=1237458156'
            '|summary=Detects the ins'
            'talled version of\n  Mantis a free popular web-based '
            'bugtracking system.\n\n  This script sends HTTP GET r'
            'equest and try to get the version from the\n  respons'
            'e, and sets the result in KB.|qod_type=remote_banner',
            '',
            '',
            'URL:http://www.mantisbt.org/',
            '3',
            '0',
            'Product detection',
            'Mantis Detection',
        ]

        custom = {
            'category':
            '3',
            'creation_date':
            '1237458156',
            'cvss_base_vector':
            'AV:N/AC:L/Au:N/C:N/I:N/A:N',
            'dependencies':
            'find_service.nasl, http_version.nasl',
            'excluded_keys':
            'Settings/disable_cgi_scanning',
            'family':
            'Product detection',
            'filename':
            'mantis_detect.nasl',
            'last_modification': ('1533906565'),
            'name':
            'Mantis Detection',
            'qod_type':
            'remote_banner',
            'required_ports':
            'Services/www, 80',
            'summary': ('Detects the installed version of\n  Mantis a '
                        'free popular web-based bugtracking system.\n'
                        '\n  This script sends HTTP GET request and t'
                        'ry to get the version from the\n  response, '
                        'and sets the result in KB.'),
            'timeout':
            '0',
        }

        mock_subps.check_output.return_value = (
            'use_mac_addr = no\ndb_address = '
            '/tmp/redis.sock\ndrop_privileges = no').encode()

        mock_redis.return_value = mock_redis
        mock_redis.config_get.return_value = {'databases': '513'}
        mock_redis.lrange.return_value = metadata
        mock_redis.keys.return_value = 1

        self.db.db_init()

        resp = self.nvti.get_nvt_metadata('1.2.3.4')
        self.assertEqual(resp, custom)

    @patch('ospd_openvas.db.subprocess')
    def test_get_nvt_metadata_fail(self, mock_subps, mock_redis):
        mock_subps.check_output.return_value = (
            'use_mac_addr = no\ndb_address = '
            '/tmp/redis.sock\ndrop_privileges = no'.encode())

        mock_redis.return_value = mock_redis
        mock_redis.config_get.return_value = {'databases': '513'}
        mock_redis.lrange.return_value = {}
        mock_redis.keys.return_value = 1

        self.db.db_init()

        resp = self.nvti.get_nvt_metadata('1.2.3.4')
        self.assertEqual(resp, None)

    @patch('ospd_openvas.db.subprocess')
    def test_get_nvt_refs(self, mock_subps, mock_redis):
        refs = ['', '', 'URL:http://www.mantisbt.org/']
        out_dict = {
            'cve': [''],
            'bid': [''],
            'xref': ['URL:http://www.mantisbt.org/'],
        }

        mock_subps.check_output.return_value = (
            'use_mac_addr = no\ndb_address = '
            '/tmp/redis.sock\ndrop_privileges = no').encode()

        mock_redis.return_value = mock_redis
        mock_redis.config_get.return_value = {'databases': '513'}
        mock_redis.lrange.return_value = refs
        mock_redis.keys.return_value = 1

        self.db.db_init()

        resp = self.nvti.get_nvt_refs('1.2.3.4')
        self.assertEqual(resp, out_dict)

    @patch('ospd_openvas.db.subprocess')
    def test_get_nvt_refs_fail(self, mock_subps, mock_redis):
        mock_subps.check_output.return_value = (
            'use_mac_addr = no\ndb_address = '
            '/tmp/redis.sock\ndrop_privileges = no'.encode())

        mock_redis.return_value = mock_redis
        mock_redis.config_get.return_value = {'databases': '513'}
        mock_redis.lrange.return_value = {}
        mock_redis.keys.return_value = 1

        self.db.db_init()

        resp = self.nvti.get_nvt_refs('1.2.3.4')
        self.assertEqual(resp, None)

    def test_get_nvt_prefs(self, mock_redis):
        prefs = ['dns-fuzz.timelimit|||entry|||default']
        mock_redis.lrange.return_value = prefs
        mock_redis.return_value = mock_redis
        resp = self.nvti.get_nvt_prefs(mock_redis(), '1.2.3.4')
        self.assertEqual(resp, prefs)

    def test_get_nvt_timeout(self, mock_redis):
        mock_redis.lindex.return_value = '300'
        mock_redis.return_value = mock_redis
        resp = self.nvti.get_nvt_timeout(mock_redis(), '1.2.3.4')
        self.assertEqual(resp, '300')

    def test_get_nvt_tag(self, mock_redis):
        tag = ('last_modification=1533906565'
               '|creation_date=1517443741|cvss_bas'
               'e_vector=AV:N/AC:L/Au:N/C:P/I:P/A:P|solution_type=V'
               'endorFix|qod_type=package|affected=rubygems on Debi'
               'an Linux|solution_method=DebianAPTUpgrade')

        out_dict = {
            'last_modification': '1533906565',
            'creation_date': '1517443741',
            'cvss_base_vector': 'AV:N/AC:L/Au:N/C:P/I:P/A:P',
            'solution_type': 'VendorFix',
            'qod_type': 'package',
            'affected': 'rubygems on Debian Linux',
            'solution_method': 'DebianAPTUpgrade',
        }

        mock_redis.lindex.return_value = tag
        mock_redis.return_value = mock_redis

        resp = self.nvti.get_nvt_tag(mock_redis(), '1.2.3.4')

        self.assertEqual(out_dict, resp)

    @patch('ospd_openvas.nvticache.NVTICache._get_gvm_libs_version_string')
    def test_set_nvti_cache_name(self, mock_version, mock_redis):
        self.assertIsNone(self.nvti._nvti_cache_name)

        mock_version.return_value = '20.10'
        self.nvti._set_nvti_cache_name()

        self.assertTrue(mock_version.called)
        self.assertEqual(self.nvti._nvti_cache_name, 'nvticache20.10')

        mock_version.reset_mock()
        mock_version.return_value = '10.0.1'

        with self.assertRaises(OspdOpenvasError):
            self.nvti._set_nvti_cache_name()

        self.assertTrue(mock_version.called)

    @patch('ospd_openvas.nvticache.NVTICache._get_gvm_libs_version_string')
    def test_get_nvti_cache_name(self, mock_version, mock_redis):
        self.assertIsNone(self.nvti._nvti_cache_name)

        mock_version.return_value = '20.4'

        self.assertEqual(self.nvti._get_nvti_cache_name(), 'nvticache20.4')
        self.assertTrue(mock_version.called)

        mock_version.reset_mock()
        mock_version.return_value = '20.10'

        self.assertEqual(self.nvti._get_nvti_cache_name(), 'nvticache20.4')
        self.assertFalse(mock_version.called)

    @patch('ospd_openvas.nvticache.subprocess')
    def test_get_gvm_libs_version_string(self, mock_subps: Mock,
                                         mock_redis: Mock):
        mock_subps.check_output.return_value = (
            'openvas 20.4.0\ngvm-libs 20.10\n'.encode())
        self.assertEqual(self.nvti._get_gvm_libs_version_string(), '20.10')

    @patch('ospd_openvas.nvticache.subprocess')
    def test_get_gvm_libs_version_string_subprocess_error(
            self, mock_subps: Mock, mock_redis: Mock):
        mock_subps.check_output.side_effect = CalledProcessError(returncode=1,
                                                                 cmd='foo bar')

        with self.assertRaises(OspdOpenvasError):
            self.nvti._get_gvm_libs_version_string()

    @patch('ospd_openvas.nvticache.subprocess')
    def test_get_gvm_libs_version_string_old_openvas(self, mock_subps: Mock,
                                                     mock_redis: Mock):
        mock_subps.check_output.side_effect = CalledProcessError(returncode=1,
                                                                 cmd='foo bar')
        mock_subps.check_output.return_value = (
            'openvas 7.0.0\nfoo bar\n'.encode())

        with self.assertRaises(OspdOpenvasError):
            self.nvti._get_gvm_libs_version_string()

    def test_is_compatible_version(self, mock_redis):
        self.assertFalse(self.nvti._is_compatible_version("1.0.0"))
        self.assertFalse(self.nvti._is_compatible_version("10.0.0"))
        self.assertTrue(self.nvti._is_compatible_version("11.0.1"))
        self.assertTrue(self.nvti._is_compatible_version("20.4"))
        self.assertTrue(self.nvti._is_compatible_version("20.4.2"))
        self.assertTrue(self.nvti._is_compatible_version("20.04"))
        self.assertTrue(self.nvti._is_compatible_version("20.10"))