Beispiel #1
0
class TestIntegrationRestDownloadFirmware(TestAcceptanceBase):

    def setUp(self):
        super().setUp()
        self._start_backend()
        self.db_backend = BackEndDbInterface(config=self.config)
        time.sleep(2)  # wait for systems to start

    def tearDown(self):
        self.db_backend.shutdown()
        self._stop_backend()
        super().tearDown()

    def _rest_search(self):
        rv = self.test_client.get('/rest/firmware?query={}'.format(urllib.parse.quote('{"device_class": "test class"}')), follow_redirects=True)
        self.assertIn(self.test_fw.uid.encode(), rv.data, "test firmware not found in rest search")

    def _rest_download(self):
        rv = self.test_client.get('/rest/binary/{}'.format(self.test_fw.uid), follow_redirects=True)
        self.assertIn(standard_b64encode(self.test_fw.binary), rv.data, "rest download response incorrect")
        self.assertIn('"file_name": "{}"'.format(self.test_fw.file_name).encode(), rv.data, "rest download response incorrect")
        self.assertIn('"SHA256": "{}"'.format(self.test_fw.sha256).encode(), rv.data, "rest download response incorrect")

    def test_run_from_upload_to_show_analysis(self):
        self.test_fw = create_test_firmware(device_class="test class", device_name="test device", vendor="test vendor")
        self.db_backend.add_firmware(self.test_fw)

        self._rest_search()
        self._rest_download()
class TestRestMissingAnalyses(RestTestBase):

    def setup(self):
        super().setup()
        self.db_backend = BackEndDbInterface(config=self.config)

    def teardown(self):
        self.db_backend.shutdown()
        super().teardown()

    def test_rest_get_missing_files(self):
        test_fw = create_test_firmware()
        missing_uid = 'uid1234'
        test_fw.files_included.add(missing_uid)
        self.db_backend.add_firmware(test_fw)

        response = json.loads(self.test_client.get('/rest/missing', follow_redirects=True).data.decode())
        assert 'missing_files' in response
        assert test_fw.uid in response['missing_files']
        assert missing_uid in response['missing_files'][test_fw.uid]
        assert response['missing_analyses'] == {}

    def test_rest_get_missing_analyses(self):
        test_fw = create_test_firmware()
        test_fo = create_test_file_object()
        test_fw.files_included.add(test_fo.uid)
        test_fo.virtual_file_path = {test_fw.uid: ['|foo|bar|']}
        test_fw.processed_analysis['foobar'] = {'foo': 'bar'}
        # test_fo is missing this analysis but is in files_included -> should count as missing analysis
        self.db_backend.add_firmware(test_fw)
        self.db_backend.add_file_object(test_fo)

        response = json.loads(self.test_client.get('/rest/missing', follow_redirects=True).data.decode())
        assert 'missing_analyses' in response
        assert test_fw.uid in response['missing_analyses']
        assert test_fo.uid in response['missing_analyses'][test_fw.uid]
        assert response['missing_files'] == {}

    def test_rest_get_failed_analyses(self):
        test_fo = create_test_file_object()
        test_fo.processed_analysis['some_analysis'] = {'failed': 'oops'}
        self.db_backend.add_file_object(test_fo)

        response = json.loads(self.test_client.get('/rest/missing', follow_redirects=True).data.decode())
        assert 'failed_analyses' in response
        assert 'some_analysis' in response['failed_analyses']
        assert test_fo.uid in response['failed_analyses']['some_analysis']

    def test_rest_get_orphaned_objects(self):
        test_fo = create_test_file_object()
        test_fo.parent_firmware_uids = ['missing_uid']
        self.db_backend.add_file_object(test_fo)

        response = json.loads(self.test_client.get('/rest/missing', follow_redirects=True).data.decode())
        assert 'orphaned_objects' in response
        assert response['orphaned_objects'] == {
            'missing_uid': ['d558c9339cb967341d701e3184f863d3928973fccdc1d96042583730b5c7b76a_62']
        }
Beispiel #3
0
class TestRestDownload(RestTestBase):
    def setup(self):
        super().setup()
        self.db_interface = BackEndDbInterface(self.config)
        self.test_queue = Queue()

    def teardown(self):
        self.test_queue.close()
        self.db_interface.shutdown()
        super().teardown()

    def test_rest_download_valid(self):
        backend_binding = InterComBackEndBinding(
            config=self.config,
            analysis_service=test_backend_scheduler.AnalysisServiceMock(),
            compare_service=test_backend_scheduler.ServiceMock(
                self.test_queue),
            unpacking_service=test_backend_scheduler.ServiceMock(
                self.test_queue))
        test_firmware = create_test_firmware(device_class='test class',
                                             device_name='test device',
                                             vendor='test vendor')
        store_binary_on_file_system(self.tmp_dir.name, test_firmware)
        self.db_interface.add_firmware(test_firmware)

        try:
            rv = self.test_client.get('/rest/binary/{}'.format(
                test_firmware.uid),
                                      follow_redirects=True)
        finally:
            backend_binding.shutdown()

        assert standard_b64encode(test_firmware.binary) in rv.data
        assert '"file_name": "{}"'.format(
            test_firmware.file_name).encode() in rv.data
        assert '"SHA256": "{}"'.format(
            test_firmware.sha256).encode() in rv.data

    def test_rest_download_invalid_uid(self):
        rv = self.test_client.get('/rest/binary/not%20existing%20uid',
                                  follow_redirects=True)

        assert b'No firmware with UID not existing uid found in database' in rv.data

    def test_rest_download_invalid_data(self):
        rv = self.test_client.get('/rest/binary/', follow_redirects=True)

        assert b'404 Not Found' in rv.data
class TestAcceptanceDownloadFile(TestAcceptanceBase):
    def setUp(self):
        super().setUp()
        self._start_backend()
        self.db_backend = BackEndDbInterface(config=self.config)
        time.sleep(10)  # wait for systems to start

    def tearDown(self):
        self.db_backend.shutdown()
        self._stop_backend()
        super().tearDown()

    def _show_analysis_page(self, fw):
        rv = self.test_client.get('/analysis/{}'.format(fw.uid))
        self.assertIn(fw.uid.encode(), rv.data)
        self.assertIn(b'test_router', rv.data)
        self.assertIn(b'Router', rv.data)
        self.assertIn(b'test_vendor', rv.data)

    def _start_binary_download(self, fw):
        rv = self.test_client.get('/download/{}'.format(fw.uid))
        self.assertIn(fw.binary, rv.data, 'firmware download unsuccessful')
        self.assertIn('attachment; filename=test.zip',
                      rv.headers['Content-Disposition'])

    def _start_tar_download(self, fw):
        rv = self.test_client.get('/tar-download/{}'.format(fw.uid))
        self.assertNotIn(
            fw.binary, rv.data,
            'tar download yielded original file instead of tar archive')
        tar_file = tarfile.open(fileobj=io.BytesIO(rv.data))
        contents = ', '.join(tar_file.getnames())
        self.assertIn('testfile1', contents,
                      'test files could not be found in tar download')

    def test_firmware_download(self):
        test_fw = create_test_firmware()
        test_fw.processed_analysis.pop('dummy')
        test_fw.uid = test_fw.get_uid()
        self.db_backend.add_firmware(test_fw)
        self.assertIsNotNone(self.db_backend.firmwares.find_one(test_fw.uid))

        self._show_analysis_page(test_fw)
        self._start_binary_download(test_fw)
        self._start_tar_download(test_fw)
Beispiel #5
0
class TestBinaryService(unittest.TestCase):
    def setUp(self):
        self.config = get_config_for_testing()
        self.mongo_server = MongoMgr(config=self.config)
        self._init_test_data()
        self.binary_service = BinaryService(config=self.config)

    def _init_test_data(self):
        self.backend_db_interface = BackEndDbInterface(config=self.config)
        self.backend_db_interface.add_firmware(TEST_FW)
        self.backend_db_interface.shutdown()

    def tearDown(self):
        self.mongo_server.shutdown()
        gc.collect()

    def test_get_binary_and_file_name(self):
        binary, file_name = self.binary_service.get_binary_and_file_name(
            TEST_FW.uid)
        self.assertEqual(file_name, TEST_FW.file_name, 'file_name not correct')
        self.assertEqual(binary, TEST_FW.binary, 'invalid result not correct')

    def test_get_binary_and_file_name_invalid_uid(self):
        binary, file_name = self.binary_service.get_binary_and_file_name(
            'invalid_uid')
        self.assertIsNone(binary, 'should be none')
        self.assertIsNone(file_name, 'should be none')

    def test_get_repacked_binary_and_file_name(self):
        tar, file_name = self.binary_service.get_repacked_binary_and_file_name(
            TEST_FW.uid)
        self.assertEqual(file_name, '{}.tar.gz'.format(TEST_FW.file_name),
                         'file_name not correct')

        file_type = magic.from_buffer(tar, mime=False)
        assert 'gzip compressed data' in file_type, 'Result is not an tar.gz file'

    def test_get_repacked_binary_and_file_name_invalid_uid(self):
        binary, file_name = self.binary_service.get_repacked_binary_and_file_name(
            'invalid_uid')
        self.assertIsNone(binary, 'should be none')
        self.assertIsNone(file_name, 'should be none')
Beispiel #6
0
class TestBinaryService:

    def setup(self):
        self.tmp_dir = TemporaryDirectory()
        self.config = get_config_for_testing(temp_dir=self.tmp_dir)
        self.mongo_server = MongoMgr(config=self.config)
        self._init_test_data()
        self.binary_service = BinaryService(config=self.config)

    def _init_test_data(self):
        self.backend_db_interface = BackEndDbInterface(config=self.config)
        self.backend_db_interface.add_firmware(TEST_FW)
        store_binary_on_file_system(self.tmp_dir.name, TEST_FW)
        self.backend_db_interface.shutdown()

    def teardown(self):
        self.tmp_dir.cleanup()
        self.mongo_server.shutdown()
        gc.collect()

    def test_get_binary_and_file_name(self):
        binary, file_name = self.binary_service.get_binary_and_file_name(TEST_FW.uid)
        assert file_name == TEST_FW.file_name, 'file_name not correct'
        assert binary == TEST_FW.binary, 'invalid result not correct'

    def test_get_binary_and_file_name_invalid_uid(self):
        binary, file_name = self.binary_service.get_binary_and_file_name('invalid_uid')
        assert binary is None, 'should be none'
        assert file_name is None, 'should be none'

    def test_get_repacked_binary_and_file_name(self):
        tar, file_name = self.binary_service.get_repacked_binary_and_file_name(TEST_FW.uid)
        assert file_name == '{}.tar.gz'.format(TEST_FW.file_name), 'file_name not correct'

        file_type = magic.from_buffer(tar, mime=False)
        assert 'gzip compressed data' in file_type, 'Result is not an tar.gz file'

    def test_get_repacked_binary_and_file_name_invalid_uid(self):
        binary, file_name = self.binary_service.get_repacked_binary_and_file_name('invalid_uid')
        assert binary is None, 'should be none'
        assert file_name is None, 'should be none'
class TestRestMissingAnalyses(RestTestBase):

    def setUp(self):
        super().setUp()
        self.db_backend = BackEndDbInterface(config=self.config)

    def tearDown(self):
        self.db_backend.shutdown()
        super().tearDown()

    def test_rest_get_missing_files(self):
        test_fw = create_test_firmware()
        missing_uid = 'uid1234'
        test_fw.files_included.add(missing_uid)
        self.db_backend.add_firmware(test_fw)

        response = json.loads(self.test_client.get('/rest/missing', follow_redirects=True).data.decode())
        assert 'missing_files' in response
        assert test_fw.uid in response['missing_files']
        assert missing_uid in response['missing_files'][test_fw.uid]
        assert response['missing_analyses'] == {}

    def test_rest_get_missing_analyses(self):
        test_fw = create_test_firmware()
        test_fo = create_test_file_object()
        test_fw.files_included.add(test_fo.uid)
        test_fo.virtual_file_path = {test_fw.uid: ['|foo|bar|']}
        test_fw.processed_analysis['foobar'] = {'foo': 'bar'}
        # test_fo is missing this analysis but is in files_included -> should count as missing analysis
        self.db_backend.add_firmware(test_fw)
        self.db_backend.add_file_object(test_fo)

        response = json.loads(self.test_client.get('/rest/missing', follow_redirects=True).data.decode())
        assert 'missing_analyses' in response
        assert test_fw.uid in response['missing_analyses']
        assert test_fo.uid in response['missing_analyses'][test_fw.uid]
        assert response['missing_files'] == {}
Beispiel #8
0
class TestAcceptanceIoRoutes(TestAcceptanceBase):

    def setUp(self):
        super().setUp()
        self._start_backend()
        self.db_backend_interface = BackEndDbInterface(self.config)
        self.test_fw = create_test_firmware(device_name='test_fw')
        self.test_fw.processed_analysis['base64_decoder'] = BASE64_ANALYSIS

    def tearDown(self):
        self.db_backend_interface.shutdown()
        self._stop_backend()
        super().tearDown()

    def test_base64_download_success(self):
        self.test_fw.processed_analysis['base64_decoder']['1019 - 1882'][0]['span_in_section'] = (0, 848, 2)
        self.test_fw.processed_analysis['base64_decoder']['1019 - 1882'][0]['span_in_binary'] = (1019, 1882)
        self.db_backend_interface.add_firmware(self.test_fw)

        response = self.test_client.get('/base64-download/{uid}/{section}/{expression_id}'.format(uid=self.test_fw.uid, section='1019 - 1882', expression_id='0'))
        self.assertIn('200', response.status, 'base64 download failed')

    def test_base64_download_bad_result(self):
        self.test_fw.processed_analysis['base64_decoder']['1019 - 1882'][0]['span_in_binary'] = None
        self.db_backend_interface.add_firmware(self.test_fw)

        response = self.test_client.get('/base64-download/{uid}/{section}/{expression_id}'.format(uid=self.test_fw.uid, section='1019 - 1882', expression_id='0'))
        self.assertIn(b'Undisclosed error in base64 decoding', response.data, 'base64 download should break')

    def test_bad_base64_encoding(self):
        self.test_fw.processed_analysis['base64_decoder']['1019 - 1882'][0]['span_in_section'] = (8, 100, 2)
        self.test_fw.processed_analysis['base64_decoder']['1019 - 1882'][0]['span_in_binary'] = (0, 1000)
        self.db_backend_interface.add_firmware(self.test_fw)

        response = self.test_client.get('/base64-download/{uid}/{section}/{expression_id}'.format(uid=self.test_fw.uid, section='1019 - 1882', expression_id='0'))
        self.assertIn(b'Incorrect padding', response.data, 'base64 did not break')

    def test_hex_dump_button(self):
        self.db_backend_interface.add_firmware(self.test_fw)

        response = self.test_client.get('/hex-dump/{uid}'.format(uid=self.test_fw.uid))
        self.assertIn('200', response.status, 'hex dump link failed')
        self.assertIn(b'0x0', response.data, 'no hex dump is shown')

    def test_hex_dump_bad_uid(self):
        response = self.test_client.get('/hex-dump/{uid}'.format(uid=self.test_fw.uid))
        self.assertIn(b'File not found in database', response.data, 'uid should not exist')

    def test_ida_download(self):
        compare_interface = CompareDbInterface(config=self.config)

        self.db_backend_interface.add_firmware(self.test_fw)

        COMPARE_RESULT['general'] = {'a': {self.test_fw.uid: 'x'}, 'b': {self.test_fw.uid: 'y'}}

        compare_interface.add_compare_result(COMPARE_RESULT)
        cid = compare_interface._calculate_compare_result_id(COMPARE_RESULT)

        response = self.test_client.get('/ida-download/{cid}'.format(cid=cid))
        self.assertIn(b'IDA database', response.data, 'mocked ida database not in result')

    def test_ida_download_bad_uid(self):
        compare_interface = CompareDbInterface(config=self.config)

        compare_interface.add_compare_result(COMPARE_RESULT)
        cid = compare_interface._calculate_compare_result_id(COMPARE_RESULT)

        response = self.test_client.get('/ida-download/{cid}'.format(cid=cid))
        self.assertIn(b'not found in database', response.data, 'endpoint should dismiss result')
Beispiel #9
0
class TestStorageDbInterfaceBackend(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._config = get_config_for_testing(TMP_DIR)
        cls.mongo_server = MongoMgr(config=cls._config)

    def setUp(self):
        self.db_interface = MongoInterfaceCommon(config=self._config)
        self.db_interface_backend = BackEndDbInterface(config=self._config)

        self.test_firmware = create_test_firmware()

        self.test_yara_match = {
            'rule': 'OpenSSH',
            'tags': [],
            'namespace': 'default',
            'strings': [(0, '$a', b'OpenSSH')],
            'meta': {
                'description': 'SSH library',
                'website': 'http://www.openssh.com',
                'open_source': True,
                'software_name': 'OpenSSH'
            },
            'matches': True
        }

        self.test_fo = create_test_file_object()

    def tearDown(self):
        self.db_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_interface_backend.shutdown()
        self.db_interface.shutdown()
        gc.collect()

    @classmethod
    def tearDownClass(cls):
        cls.mongo_server.shutdown()
        TMP_DIR.cleanup()

    def _get_all_firmware_uids(self):
        uid_list = []
        tmp = self.db_interface.firmwares.find()
        for item in tmp:
            uid_list.append(item['_id'])
        return uid_list

    def test_add_firmware(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertGreater(len(self._get_all_firmware_uids()), 0,
                           'No entry added to DB')
        recoverd_firmware_entry = self.db_interface_backend.firmwares.find_one(
        )
        self.assertAlmostEqual(recoverd_firmware_entry['submission_date'],
                               time(),
                               msg='submission time not set correctly',
                               delta=5.0)

    def test_add_and_get_firmware(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        result_backend = self.db_interface_backend.get_firmware(
            self.test_firmware.uid)
        self.assertIsNotNone(result_backend.binary,
                             'binary not set in backend result')
        result_common = self.db_interface.get_firmware(self.test_firmware.uid)
        self.assertIsNone(result_common.binary, 'binary set in common result')
        self.assertEqual(result_common.size, 787,
                         'file size not correct in common')
        self.assertIsInstance(result_common.tags, dict,
                              'tag field type not correct')

    def test_add_and_get_file_object(self):
        self.db_interface_backend.add_file_object(self.test_fo)
        result_backend = self.db_interface_backend.get_file_object(
            self.test_fo.uid)
        self.assertIsNotNone(result_backend.binary,
                             'binary not set in backend result')
        result_common = self.db_interface.get_file_object(self.test_fo.uid)
        self.assertIsNone(result_common.binary, 'binary set in common result')
        self.assertEqual(result_common.size, 62,
                         'file size not correct in common')

    def test_update_firmware(self):
        first_dict = {
            'stub_plugin': {
                'result': 0
            },
            'other_plugin': {
                'field': 'day'
            }
        }
        second_dict = {'stub_plugin': {'result': 1}}

        self.test_firmware.processed_analysis = first_dict
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertEqual(
            0,
            self.db_interface.get_object(
                self.test_firmware.uid).processed_analysis['stub_plugin']
            ['result'])
        self.test_firmware.processed_analysis = second_dict
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertEqual(
            1,
            self.db_interface.get_object(
                self.test_firmware.uid).processed_analysis['stub_plugin']
            ['result'])
        self.assertIn(
            'other_plugin',
            self.db_interface.get_object(
                self.test_firmware.uid).processed_analysis.keys())

    def test_update_file_object(self):
        first_dict = {'other_plugin': {'result': 0}}
        second_dict = {'stub_plugin': {'result': 1}}

        self.test_fo.processed_analysis = first_dict
        self.test_fo.files_included = {'file a', 'file b'}
        self.db_interface_backend.add_file_object(self.test_fo)
        self.test_fo.processed_analysis = second_dict
        self.test_fo.files_included = {'file b', 'file c'}
        self.db_interface_backend.add_file_object(self.test_fo)
        received_object = self.db_interface.get_object(self.test_fo.uid)
        self.assertEqual(
            0, received_object.processed_analysis['other_plugin']['result'])
        self.assertEqual(
            1, received_object.processed_analysis['stub_plugin']['result'])
        self.assertEqual(3, len(received_object.files_included))

    def test_add_and_get_object_including_comment(self):
        comment, author, date, uid = 'this is a test comment!', 'author', '1473431685', self.test_fo.uid
        self.test_fo.comments.append({
            'time': str(date),
            'author': author,
            'comment': comment
        })
        self.db_interface_backend.add_file_object(self.test_fo)

        retrieved_comment = self.db_interface.get_object(uid).comments[0]
        self.assertEqual(author, retrieved_comment['author'])
        self.assertEqual(comment, retrieved_comment['comment'])
        self.assertEqual(date, retrieved_comment['time'])

    def test_update_analysis_tag_no_firmware(self):
        self.db_interface_backend.add_file_object(self.test_fo)
        tag = {'value': 'yay', 'color': 'default', 'propagate': True}

        self.db_interface_backend.update_analysis_tags(self.test_fo.uid,
                                                       plugin_name='dummy',
                                                       tag_name='some_tag',
                                                       tag=tag)
        processed_fo = self.db_interface_backend.get_object(self.test_fo.uid)

        assert not processed_fo.analysis_tags

    def test_update_analysis_tag_uid_not_found(self):
        self.db_interface_backend.update_analysis_tags(self.test_fo.uid,
                                                       plugin_name='dummy',
                                                       tag_name='some_tag',
                                                       tag='should not matter')
        assert not self.db_interface_backend.get_object(self.test_fo.uid)

    def test_update_analysis_tag_bad_tag(self):
        self.db_interface_backend.add_firmware(self.test_firmware)

        self.db_interface_backend.update_analysis_tags(self.test_firmware.uid,
                                                       plugin_name='dummy',
                                                       tag_name='some_tag',
                                                       tag='bad_tag')
        processed_firmware = self.db_interface_backend.get_object(
            self.test_firmware.uid)

        assert not processed_firmware.analysis_tags

    def test_update_analysis_tag_success(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        tag = {'value': 'yay', 'color': 'default', 'propagate': True}

        self.db_interface_backend.update_analysis_tags(self.test_firmware.uid,
                                                       plugin_name='dummy',
                                                       tag_name='some_tag',
                                                       tag=tag)
        processed_firmware = self.db_interface_backend.get_object(
            self.test_firmware.uid)

        assert processed_firmware.analysis_tags
        assert processed_firmware.analysis_tags['dummy']['some_tag'] == tag

    def test_add_analysis_firmware(self):
        self.db_interface_backend.add_object(self.test_firmware)
        before = self.db_interface_backend.get_object(
            self.test_firmware.uid).processed_analysis

        self.test_firmware.processed_analysis['foo'] = {'bar': 5}
        self.db_interface_backend.add_analysis(self.test_firmware)
        after = self.db_interface_backend.get_object(
            self.test_firmware.uid).processed_analysis

        assert before != after
        assert 'foo' not in before
        assert 'foo' in after
        assert after['foo'] == {'bar': 5}

    def test_add_analysis_file_object(self):
        self.db_interface_backend.add_object(self.test_fo)

        self.test_fo.processed_analysis['foo'] = {'bar': 5}
        self.db_interface_backend.add_analysis(self.test_fo)
        analysis = self.db_interface_backend.get_object(
            self.test_fo.uid).processed_analysis

        assert 'foo' in analysis
        assert analysis['foo'] == {'bar': 5}

    def test_crash_add_analysis(self):
        with self.assertRaises(RuntimeError):
            self.db_interface_backend.add_analysis(dict())

        with self.assertRaises(AttributeError):
            self.db_interface_backend._update_analysis(dict(), 'dummy', dict())
Beispiel #10
0
class TestStorageDbInterfaceFrontend(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._config = get_config_for_testing(TMP_DIR)
        cls.mongo_server = MongoMgr(config=cls._config)

    def setUp(self):
        self.db_frontend_interface = FrontEndDbInterface(config=self._config)
        self.db_backend_interface = BackEndDbInterface(config=self._config)
        self.test_firmware = create_test_firmware()

    def tearDown(self):
        self.db_frontend_interface.shutdown()
        self.db_backend_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_backend_interface.shutdown()
        gc.collect()

    @classmethod
    def tearDownClass(cls):
        cls.mongo_server.shutdown()
        TMP_DIR.cleanup()

    def test_regression_meta_list(self):
        assert self.test_firmware.processed_analysis.pop('unpacker')
        self.db_backend_interface.add_firmware(self.test_firmware)
        list_of_firmwares = self.db_frontend_interface.get_meta_list()
        assert 'NOP' in list_of_firmwares.pop()[2]

    def test_get_meta_list(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        list_of_firmwares = self.db_frontend_interface.get_meta_list()
        test_output = list_of_firmwares.pop()
        self.assertEqual(test_output[1],
                         'test_vendor test_router - 0.1 (Router)',
                         'Firmware not successfully received')
        self.assertIsInstance(test_output[2], dict, 'tag field is not a dict')

    def test_get_meta_list_of_fo(self):
        test_fo = create_test_file_object()
        self.db_backend_interface.add_file_object(test_fo)
        files = self.db_frontend_interface.file_objects.find()
        meta_list = self.db_frontend_interface.get_meta_list(files)
        self.assertEqual(meta_list[0][0], test_fo.uid,
                         'uid of object not correct')
        self.assertEqual(meta_list[0][3], 0,
                         'non existing submission date should lead to 0')

    def test_get_hid_firmware(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        result = self.db_frontend_interface.get_hid(self.test_firmware.uid)
        self.assertEqual(result, 'test_vendor test_router - 0.1 (Router)',
                         'fw hid not correct')

    def test_get_hid_fo(self):
        test_fo = create_test_file_object(bin_path='get_files_test/testfile2')
        test_fo.virtual_file_path = {
            'a': ['|a|/test_file'],
            'b': ['|b|/get_files_test/testfile2']
        }
        self.db_backend_interface.add_file_object(test_fo)
        result = self.db_frontend_interface.get_hid(test_fo.uid, root_uid='b')
        self.assertEqual(result, '/get_files_test/testfile2',
                         'fo hid not correct')
        result = self.db_frontend_interface.get_hid(test_fo.uid)
        self.assertIsInstance(result, str, 'result is not a string')
        self.assertEqual(result[0], '/',
                         'first character not correct if no root_uid set')
        result = self.db_frontend_interface.get_hid(test_fo.uid, root_uid='c')
        self.assertEqual(
            result[0], '/',
            'first character not correct if invalid root_uid set')

    def test_get_file_name(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        result = self.db_frontend_interface.get_file_name(
            self.test_firmware.uid)
        self.assertEqual(result, 'test.zip', 'name not correct')

    def test_get_hid_invalid_uid(self):
        result = self.db_frontend_interface.get_hid('foo')
        self.assertEqual(result, '',
                         'invalid uid should result in empty string')

    def test_get_firmware_attribute_list(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.assertEqual(self.db_frontend_interface.get_device_class_list(),
                         ['Router'])
        self.assertEqual(self.db_frontend_interface.get_vendor_list(),
                         ['test_vendor'])
        self.assertEqual(
            self.db_frontend_interface.get_firmware_attribute_list(
                'device_name', {
                    'vendor': 'test_vendor',
                    'device_class': 'Router'
                }), ['test_router'])
        self.assertEqual(
            self.db_frontend_interface.get_firmware_attribute_list('version'),
            ['0.1'])
        self.assertEqual(self.db_frontend_interface.get_device_name_dict(),
                         {'Router': {
                             'test_vendor': ['test_router']
                         }})

    def test_get_data_for_nice_list(self):
        uid_list = [self.test_firmware.uid]
        self.db_backend_interface.add_firmware(self.test_firmware)
        nice_list_data = self.db_frontend_interface.get_data_for_nice_list(
            uid_list, uid_list[0])
        self.assertEqual(
            sorted([
                'size', 'virtual_file_paths', 'uid', 'mime-type',
                'files_included'
            ]), sorted(nice_list_data[0].keys()))
        self.assertEqual(nice_list_data[0]['uid'], self.test_firmware.uid)

    def test_generic_search(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        # str input
        result = self.db_frontend_interface.generic_search(
            '{"file_name": "test.zip"}')
        self.assertEqual(result, [self.test_firmware.uid],
                         'Firmware not successfully received')
        # dict input
        result = self.db_frontend_interface.generic_search(
            {'file_name': 'test.zip'})
        self.assertEqual(result, [self.test_firmware.uid],
                         'Firmware not successfully received')

    def test_all_uids_found_in_database(self):
        self.db_backend_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        uid_list = [self.test_firmware.uid]
        self.assertFalse(
            self.db_frontend_interface.all_uids_found_in_database(uid_list))
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.assertTrue(
            self.db_frontend_interface.all_uids_found_in_database(
                [self.test_firmware.uid]))

    def test_get_x_last_added_firmwares(self):
        self.assertEqual(self.db_frontend_interface.get_last_added_firmwares(),
                         [], 'empty db should result in empty list')
        test_fw_one = create_test_firmware(device_name='fw_one')
        self.db_backend_interface.add_firmware(test_fw_one)
        test_fw_two = create_test_firmware(device_name='fw_two',
                                           bin_path='container/test.7z')
        self.db_backend_interface.add_firmware(test_fw_two)
        test_fw_three = create_test_firmware(device_name='fw_three',
                                             bin_path='container/test.cab')
        self.db_backend_interface.add_firmware(test_fw_three)
        result = self.db_frontend_interface.get_last_added_firmwares(limit_x=2)
        self.assertEqual(len(result), 2, 'Number of results should be 2')
        self.assertEqual(result[0][0], test_fw_three.uid,
                         'last firmware is not first entry')
        self.assertEqual(result[1][0], test_fw_two.uid,
                         'second last firmware is not the second entry')

    def test_generate_file_tree_level(self):
        parent_fw = create_test_firmware()
        child_fo = create_test_file_object()
        child_fo.processed_analysis['file_type'] = {'mime': 'sometype'}
        uid = parent_fw.uid
        child_fo.virtual_file_path = {
            uid: ['|{}|/folder/{}'.format(uid, child_fo.file_name)]
        }
        parent_fw.files_included = {child_fo.uid}
        self.db_backend_interface.add_object(parent_fw)
        self.db_backend_interface.add_object(child_fo)
        for node in self.db_frontend_interface.generate_file_tree_level(
                uid, uid):
            self.assertIsInstance(node, FileTreeNode)
            self.assertEqual(node.name, parent_fw.file_name)
            self.assertTrue(node.has_children)
        for node in self.db_frontend_interface.generate_file_tree_level(
                child_fo.uid, uid):
            self.assertIsInstance(node, FileTreeNode)
            self.assertEqual(node.name, 'folder')
            self.assertTrue(node.has_children)
            virtual_grand_child = node.get_list_of_child_nodes()[0]
            self.assertEqual(virtual_grand_child.type, 'sometype')
            self.assertFalse(virtual_grand_child.has_children)
            self.assertEqual(virtual_grand_child.name, child_fo.file_name)

    def test_get_number_of_total_matches(self):
        parent_fw = create_test_firmware()
        child_fo = create_test_file_object()
        uid = parent_fw.uid
        child_fo.virtual_file_path = {
            uid: ['|{}|/folder/{}'.format(uid, child_fo.file_name)]
        }
        self.db_backend_interface.add_object(parent_fw)
        self.db_backend_interface.add_object(child_fo)
        query = '{{"$or": [{{"_id": "{}"}}, {{"_id": "{}"}}]}}'.format(
            uid, child_fo.uid)
        self.assertEqual(
            self.db_frontend_interface.get_number_of_total_matches(
                query, only_parent_firmwares=False), 2)
        self.assertEqual(
            self.db_frontend_interface.get_number_of_total_matches(
                query, only_parent_firmwares=True), 1)

    def test_get_other_versions_of_firmware(self):
        parent_fw1 = create_test_firmware(version='1')
        self.db_backend_interface.add_object(parent_fw1)
        parent_fw2 = create_test_firmware(version='2',
                                          bin_path='container/test.7z')
        self.db_backend_interface.add_object(parent_fw2)
        parent_fw3 = create_test_firmware(version='3',
                                          bin_path='container/test.cab')
        self.db_backend_interface.add_object(parent_fw3)

        other_versions = self.db_frontend_interface.get_other_versions_of_firmware(
            parent_fw1)
        self.assertEqual(len(other_versions), 2,
                         'wrong number of other versions')
        self.assertIn({'_id': parent_fw2.uid, 'version': '2'}, other_versions)
        self.assertIn({'_id': parent_fw3.uid, 'version': '3'}, other_versions)

        other_versions = self.db_frontend_interface.get_other_versions_of_firmware(
            parent_fw2)
        self.assertIn({'_id': parent_fw3.uid, 'version': '3'}, other_versions)

    def test_get_specific_fields_for_multiple_entries(self):
        test_fw_1 = create_test_firmware(device_name='fw_one',
                                         vendor='test_vendor_one')
        self.db_backend_interface.add_firmware(test_fw_1)
        test_fw_2 = create_test_firmware(device_name='fw_two',
                                         vendor='test_vendor_two',
                                         bin_path='container/test.7z')
        self.db_backend_interface.add_firmware(test_fw_2)
        test_fo = create_test_file_object()
        self.db_backend_interface.add_file_object(test_fo)

        test_uid_list = [test_fw_1.uid, test_fw_2.uid]
        result = list(
            self.db_frontend_interface.
            get_specific_fields_for_multiple_entries(uid_list=test_uid_list,
                                                     field_dict={
                                                         'vendor': 1,
                                                         'device_name': 1
                                                     }))
        assert len(result) == 2
        assert all(
            set(entry.keys()) == {'_id', 'vendor', 'device_name'}
            for entry in result)
        result_uids = [entry['_id'] for entry in result]
        assert all(uid in result_uids for uid in test_uid_list)

        test_uid_list = [test_fw_1.uid, test_fo.uid]
        result = list(
            self.db_frontend_interface.
            get_specific_fields_for_multiple_entries(
                uid_list=test_uid_list, field_dict={'virtual_file_path': 1}))
        assert len(result) == 2
        assert all(
            set(entry.keys()) == {'_id', 'virtual_file_path'}
            for entry in result)
        result_uids = [entry['_id'] for entry in result]
        assert all(uid in result_uids for uid in test_uid_list)

    def test_find_missing_files(self):
        test_fw_1 = create_test_firmware()
        test_fw_1.files_included.add('uid1234')
        self.db_backend_interface.add_firmware(test_fw_1)
        missing_files = self.db_frontend_interface.find_missing_files()
        assert test_fw_1.uid in missing_files
        assert missing_files[test_fw_1.uid] == {'uid1234'}

        test_fo = create_test_file_object()
        test_fo.uid = 'uid1234'
        self.db_backend_interface.add_file_object(test_fo)
        missing_files = self.db_frontend_interface.find_missing_files()
        assert missing_files == {}

    def test_find_missing_analyses(self):
        test_fw_1 = create_test_firmware()
        test_fo = create_test_file_object()
        test_fw_1.files_included.add(test_fo.uid)
        test_fo.virtual_file_path = {test_fw_1.uid: ['|foo|bar|']}
        self.db_backend_interface.add_firmware(test_fw_1)
        self.db_backend_interface.add_file_object(test_fo)

        missing_analyses = self.db_frontend_interface.find_missing_analyses()
        assert missing_analyses == {}

        test_fw_1.processed_analysis['foobar'] = {'foo': 'bar'}
        self.db_backend_interface.add_analysis(test_fw_1)
        missing_analyses = self.db_frontend_interface.find_missing_analyses()
        assert test_fw_1.uid in missing_analyses
        assert missing_analyses[test_fw_1.uid] == {test_fo.uid}
Beispiel #11
0
class TestRestStartCompare(RestTestBase):
    def setup(self):
        super().setup()
        self.db_backend = BackEndDbInterface(config=self.config)

    def teardown(self):
        self.db_backend.shutdown()
        super().teardown()

    def test_rest_start_compare_valid(self):
        test_firmware_1 = create_test_firmware(device_class="test class",
                                               device_name="test device",
                                               vendor="test vendor")
        test_firmware_2 = create_test_firmware(device_class="test class",
                                               device_name="test device",
                                               vendor="test vendor",
                                               bin_path="container/test.7z")
        self.db_backend.add_firmware(test_firmware_1)
        self.db_backend.add_firmware(test_firmware_2)

        rv = self.test_client.put(
            '/rest/compare',
            data=json.dumps({
                "uid_list": [test_firmware_1.uid, test_firmware_2.uid],
                "redo":
                True
            }),
            follow_redirects=True)
        assert b"Compare started." in rv.data

    def test_rest_start_compare_invalid_uid(self):
        rv = self.test_client.put('/rest/compare',
                                  data=json.dumps({"uid_list": ["123",
                                                                "456"]}),
                                  follow_redirects=True)
        assert b"not found in database" in rv.data

    def test_rest_start_compare_invalid_data(self):
        test_firmware = create_test_firmware(device_class="test class",
                                             device_name="test device",
                                             vendor="test vendor")
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.put('/rest/compare',
                                  data=json.dumps({"data": "invalid data"}),
                                  follow_redirects=True)
        assert b"Request should be of the form" in rv.data

    def test_rest_get_compare_valid_not_in_db(self):
        test_firmware_1 = create_test_firmware(device_class="test class",
                                               device_name="test device",
                                               vendor="test vendor")
        test_firmware_2 = create_test_firmware(device_class="test class",
                                               device_name="test device",
                                               vendor="test vendor",
                                               bin_path="container/test.7z")
        self.db_backend.add_firmware(test_firmware_1)
        self.db_backend.add_firmware(test_firmware_2)

        rv = self.test_client.get('/rest/compare/{};{}'.format(
            test_firmware_1.uid, test_firmware_2.uid),
                                  follow_redirects=True)
        assert b"Compare not found in database." in rv.data

    def test_rest_get_compare_invalid_uid(self):
        rv = self.test_client.get('/rest/compare/123;456',
                                  follow_redirects=True)
        assert b"not found in database" in rv.data

    def test_rest_get_compare_invalid_data(self):
        test_firmware = create_test_firmware(device_class="test class",
                                             device_name="test device",
                                             vendor="test vendor")
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/compare', follow_redirects=True)
        assert b"Compare ID must be of the form" in rv.data
class TestStorageDbInterfaceAdmin(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.config = get_config_for_testing(TMP_DIR)
        cls.config.set('data_storage', 'sanitize_database', 'tmp_sanitize')
        cls.config.set('data_storage', 'report_threshold', '32')
        cls.mongo_server = MongoMgr(config=cls.config)

    def setUp(self):
        self.admin_interface = AdminDbInterface(config=self.config)
        self.db_backend_interface = BackEndDbInterface(config=self.config)
        copyfile(test_firmware_original, test_firmware_copy)
        self.test_firmware = create_test_firmware(
            bin_path='container/test_copy.zip')
        self.uid = self.test_firmware.get_uid()
        self.test_firmware.virtual_file_path = {
            self.uid: ['|{}|'.format(self.test_firmware.get_uid())]
        }
        copyfile(test_file_original, test_file_copy)
        self.child_fo = create_test_file_object(test_file_copy)
        self.child_fo.virtual_file_path = {
            self.uid:
            ['|{}|/folder/{}'.format(self.uid, self.child_fo.file_name)]
        }
        self.test_firmware.files_included = [self.child_fo.get_uid()]
        self.child_uid = self.child_fo.get_uid()

    def tearDown(self):
        self.admin_interface.client.drop_database(
            self.config.get('data_storage', 'main_database'))
        self.admin_interface.client.drop_database(
            self.config.get('data_storage', 'sanitize_database'))
        self.admin_interface.shutdown()
        self.db_backend_interface.shutdown()
        gc.collect()

    @classmethod
    def tearDownClass(cls):
        cls.mongo_server.shutdown()
        for test_file in [test_file_copy, test_firmware_copy]:
            if os.path.isfile(test_file):
                os.remove(test_file)
        TMP_DIR.cleanup()

    def test_remove_object_field(self):
        self.db_backend_interface.add_file_object(self.child_fo)
        self.assertIn(
            self.uid,
            self.db_backend_interface.file_objects.find_one(
                self.child_uid, {'virtual_file_path': 1})['virtual_file_path'])
        self.admin_interface.remove_object_field(
            self.child_uid, 'virtual_file_path.{}'.format(self.uid))
        self.assertNotIn(
            self.uid,
            self.db_backend_interface.file_objects.find_one(
                self.child_uid, {'virtual_file_path': 1})['virtual_file_path'])

    def test_remove_virtual_path_entries_no_other_roots(self):
        self.db_backend_interface.add_file_object(self.child_fo)
        self.assertIn(
            self.uid,
            self.db_backend_interface.file_objects.find_one(
                self.child_uid, {'virtual_file_path': 1})['virtual_file_path'])
        removed_vps, deleted_files = self.admin_interface._remove_virtual_path_entries(
            self.uid, self.child_fo.get_uid())
        self.assertIsNone(
            self.db_backend_interface.file_objects.find_one(self.child_uid))
        self.assertEqual(removed_vps, 0)
        self.assertEqual(deleted_files, 1)

    def test_remove_virtual_path_entries_other_roots(self):
        self.child_fo.virtual_file_path.update(
            {'someuid': ['|someuid|/some/virtual/path']})
        self.db_backend_interface.add_file_object(self.child_fo)
        self.assertIn(
            self.uid,
            self.db_backend_interface.file_objects.find_one(
                self.child_uid, {'virtual_file_path': 1})['virtual_file_path'])
        removed_vps, deleted_files = self.admin_interface._remove_virtual_path_entries(
            self.uid, self.child_fo.get_uid())
        self.assertNotIn(
            self.uid,
            self.db_backend_interface.file_objects.find_one(
                self.child_uid, {'virtual_file_path': 1})['virtual_file_path'])
        self.assertEqual(removed_vps, 1)
        self.assertEqual(deleted_files, 0)

    def test_delete_swapped_analysis_entries(self):
        self.test_firmware.processed_analysis = {
            'test_plugin': {
                'result': 10000000000,
                'misc': 'delete_swap_test'
            }
        }
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.admin_interface.client.drop_database(
            self.config.get('data_storage', 'sanitize_database'))
        self.admin_interface.sanitize_analysis(
            self.test_firmware.processed_analysis, self.uid)
        self.assertIn(
            'test_plugin_result_{}'.format(self.test_firmware.get_uid()),
            self.admin_interface.sanitize_fs.list())
        self.admin_interface._delete_swapped_analysis_entries(
            self.admin_interface.firmwares.find_one(self.uid))
        self.assertNotIn(
            'test_plugin_result_{}'.format(self.test_firmware.get_uid()),
            self.admin_interface.sanitize_fs.list())

    def test_delete_file_object(self):
        self.db_backend_interface.add_file_object(self.child_fo)
        db_entry = self.db_backend_interface.file_objects.find_one(
            self.child_fo.get_uid())
        self.assertIsNotNone(db_entry)
        self.admin_interface._delete_file_object(db_entry)
        self.assertIsNone(
            self.db_backend_interface.file_objects.find_one(
                self.child_fo.get_uid()), 'file not deleted from db')
        delete_tasks = self._get_delete_tasks()
        self.assertIn(self.child_fo.get_uid(), delete_tasks,
                      'file not found in delete tasks')

    def test_delete_firmware(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.db_backend_interface.add_file_object(self.child_fo)
        self.assertIsNotNone(
            self.db_backend_interface.firmwares.find_one(self.uid))
        self.assertIsNotNone(
            self.db_backend_interface.file_objects.find_one(self.child_uid))
        self.assertTrue(os.path.isfile(self.test_firmware.file_path))
        self.assertTrue(os.path.isfile(self.child_fo.file_path))
        removed_vps, deleted_files = self.admin_interface.delete_firmware(
            self.uid)
        self.assertIsNone(
            self.db_backend_interface.firmwares.find_one(self.uid),
            'firmware not deleted from db')
        self.assertIsNone(
            self.db_backend_interface.file_objects.find_one(self.child_uid),
            'child not deleted from db')
        self.assertEqual(removed_vps, 0)
        self.assertEqual(deleted_files, 2,
                         'number of removed files not correct')

        # check if file delete tasks were created
        delete_tasks = self._get_delete_tasks()
        self.assertIn(self.test_firmware.get_uid(), delete_tasks,
                      'fw delete task not found')
        self.assertIn(self.child_fo.get_uid(), delete_tasks,
                      'child delete task not found')
        self.assertEqual(len(delete_tasks), 2,
                         'number of delete tasks not correct')

    def _get_delete_tasks(self):
        intercom = InterComListener(config=self.config)
        intercom.CONNECTION_TYPE = 'file_delete_task'
        delete_tasks = []
        while True:
            tmp = intercom.get_next_task()
            if tmp is None:
                break
            else:
                delete_tasks.append(tmp['_id'])
        intercom.shutdown()
        return delete_tasks
Beispiel #13
0
class TestMongoInterface(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._config = get_config_for_testing(TMP_DIR)
        cls._config.set('data_storage', 'report_threshold', '32')
        cls._config.set('data_storage', 'sanitize_database', 'tmp_sanitize')
        cls.mongo_server = MongoMgr(config=cls._config)

    def setUp(self):
        self.db_interface = MongoInterfaceCommon(config=self._config)
        self.db_interface_backend = BackEndDbInterface(config=self._config)

        self.test_firmware = create_test_firmware()

        self.test_yara_match = {
            'rule': 'OpenSSH',
            'tags': [],
            'namespace': 'default',
            'strings': [(0, '$a', b'OpenSSH')],
            'meta': {
                'description': 'SSH library',
                'website': 'http://www.openssh.com',
                'open_source': True,
                'software_name': 'OpenSSH'
            },
            'matches': True
        }

        self.test_fo = create_test_file_object()

    def tearDown(self):
        self.db_interface_backend.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_interface_backend.shutdown()
        self.db_interface.client.drop_database(
            self._config.get('data_storage', 'sanitize_database'))
        self.db_interface.shutdown()
        gc.collect()

    @classmethod
    def tearDownClass(cls):
        cls.mongo_server.shutdown()
        TMP_DIR.cleanup()

    def _get_all_firmware_uids(self):
        uid_list = []
        tmp = self.db_interface.firmwares.find()
        for item in tmp:
            uid_list.append(item['_id'])
        return uid_list

    def test_existence_quick_check(self):
        self.assertFalse(
            self.db_interface.existence_quick_check('none_existing'),
            'none existing firmware found')
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertTrue(
            self.db_interface.existence_quick_check(self.test_firmware.uid),
            'existing firmware not found')
        self.db_interface_backend.add_file_object(self.test_fo)
        self.assertTrue(
            self.db_interface.existence_quick_check(self.test_fo.uid),
            'existing file not found')

    def test_get_firmware(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        fobject = self.db_interface.get_firmware(self.test_firmware.uid)
        self.assertEqual(fobject.vendor, 'test_vendor')
        self.assertEqual(fobject.device_name, 'test_router')
        self.assertEqual(fobject.part, '')

    def test_get_object(self):
        fo = self.db_interface.get_object(self.test_firmware.uid)
        self.assertIsNone(
            fo, 'found something but there is nothing in the database')
        self.db_interface_backend.add_firmware(self.test_firmware)
        fo = self.db_interface.get_object(self.test_firmware.uid)
        self.assertIsInstance(fo, Firmware, 'firmware has wrong type')
        self.assertEqual(fo.device_name, 'test_router',
                         'Device name in Firmware not correct')
        test_file = FileObject(file_path=path.join(get_test_data_dir(),
                                                   'get_files_test/testfile2'))
        self.db_interface_backend.add_file_object(test_file)
        fo = self.db_interface.get_object(test_file.uid)
        self.assertIsInstance(fo, FileObject, 'file object has wrong type')

    def test_get_complete_object_including_all_summaries(self):
        self.db_interface_backend.report_threshold = 1024
        test_file = create_test_file_object()
        self.test_firmware.add_included_file(test_file)
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.db_interface_backend.add_file_object(test_file)
        tmp = self.db_interface.get_complete_object_including_all_summaries(
            self.test_firmware.uid)
        self.assertIsInstance(tmp, Firmware, 'wrong type')
        self.assertIn('summary', tmp.processed_analysis['dummy'].keys(),
                      'summary not found in processed analysis')
        self.assertIn('sum a', tmp.processed_analysis['dummy']['summary'],
                      'summary of original file not included')
        self.assertIn('file exclusive sum b',
                      tmp.processed_analysis['dummy']['summary'],
                      'summary of included file not found')

    def test_sanitize_analysis(self):
        short_dict = {'stub_plugin': {'result': 0}}
        long_dict = {
            'stub_plugin': {
                'result': 10000000000,
                'misc': 'Bananarama',
                'summary': []
            }
        }

        self.test_firmware.processed_analysis = short_dict
        sanitized_dict = self.db_interface.sanitize_analysis(
            self.test_firmware.processed_analysis, self.test_firmware.uid)
        self.assertIn('file_system_flag', sanitized_dict['stub_plugin'].keys())
        self.assertFalse(sanitized_dict['stub_plugin']['file_system_flag'])
        self.assertEqual(self.db_interface.sanitize_fs.list(), [],
                         'file stored in db but should not')

        self.test_firmware.processed_analysis = long_dict
        sanitized_dict = self.db_interface.sanitize_analysis(
            self.test_firmware.processed_analysis, self.test_firmware.uid)
        self.assertIn('stub_plugin_result_{}'.format(self.test_firmware.uid),
                      self.db_interface.sanitize_fs.list(),
                      'sanitized file not stored')
        self.assertNotIn('summary_result_{}'.format(self.test_firmware.uid),
                         self.db_interface.sanitize_fs.list(),
                         'summary is erroneously stored')
        self.assertIn('file_system_flag', sanitized_dict['stub_plugin'].keys())
        self.assertTrue(sanitized_dict['stub_plugin']['file_system_flag'])
        self.assertEqual(type(sanitized_dict['stub_plugin']['summary']), list)

    def test_sanitize_db_duplicates(self):
        long_dict = {
            'stub_plugin': {
                'result': 10000000000,
                'misc': 'Bananarama',
                'summary': []
            }
        }
        gridfs_file_name = 'stub_plugin_result_{}'.format(
            self.test_firmware.uid)

        self.test_firmware.processed_analysis = long_dict
        assert self.db_interface.sanitize_fs.find({
            'filename': gridfs_file_name
        }).count() == 0
        self.db_interface.sanitize_analysis(
            self.test_firmware.processed_analysis, self.test_firmware.uid)
        assert self.db_interface.sanitize_fs.find({
            'filename': gridfs_file_name
        }).count() == 1
        self.db_interface.sanitize_analysis(
            self.test_firmware.processed_analysis, self.test_firmware.uid)
        assert self.db_interface.sanitize_fs.find({
            'filename': gridfs_file_name
        }).count() == 1, 'duplicate entry was created'
        md5 = self.db_interface.sanitize_fs.find_one({
            'filename':
            gridfs_file_name
        }).md5

        long_dict['stub_plugin']['result'] += 1  # new analysis result
        self.db_interface.sanitize_analysis(
            self.test_firmware.processed_analysis, self.test_firmware.uid)
        assert self.db_interface.sanitize_fs.find({
            'filename': gridfs_file_name
        }).count() == 1, 'duplicate entry was created'
        assert self.db_interface.sanitize_fs.find_one({
            'filename':
            gridfs_file_name
        }).md5 != md5, 'hash of new file did not change'

    def test_retrieve_analysis(self):
        self.db_interface.sanitize_fs.put(pickle.dumps('This is a test!'),
                                          filename='test_file_path')

        sanitized_dict = {
            'stub_plugin': {
                'result': 'test_file_path',
                'file_system_flag': True
            }
        }
        sanitized_dict['inbound_result'] = {
            'result': 'inbound result',
            'file_system_flag': False
        }
        retrieved_dict = self.db_interface.retrieve_analysis(sanitized_dict)

        self.assertNotIn('file_system_flag',
                         retrieved_dict['stub_plugin'].keys())
        self.assertIn('result', retrieved_dict['stub_plugin'].keys())
        self.assertEqual(retrieved_dict['stub_plugin']['result'],
                         'This is a test!')
        self.assertNotIn('file_system_flag',
                         retrieved_dict['inbound_result'].keys())
        self.assertEqual(retrieved_dict['inbound_result']['result'],
                         'inbound result')

    def test_retrieve_analysis_filter(self):
        self.db_interface.sanitize_fs.put(pickle.dumps('This is a test!'),
                                          filename='test_file_path')
        sanitized_dict = {
            'selected_plugin': {
                'result': 'test_file_path',
                'file_system_flag': True
            }
        }
        sanitized_dict['other_plugin'] = {
            'result': 'test_file_path',
            'file_system_flag': True
        }
        retrieved_dict = self.db_interface.retrieve_analysis(
            sanitized_dict, analysis_filter=['selected_plugin'])
        self.assertEqual(retrieved_dict['selected_plugin']['result'],
                         'This is a test!')
        self.assertIn('file_system_flag', retrieved_dict['other_plugin'])

    def test_get_objects_by_uid_list(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        fo_list = self.db_interface.get_objects_by_uid_list(
            [self.test_firmware.uid])
        self.assertIsInstance(fo_list[0], Firmware, 'firmware has wrong type')
        self.assertEqual(fo_list[0].device_name, 'test_router',
                         'Device name in Firmware not correct')
        test_file = FileObject(file_path=path.join(get_test_data_dir(),
                                                   'get_files_test/testfile2'))
        self.db_interface_backend.add_file_object(test_file)
        fo_list = self.db_interface.get_objects_by_uid_list([test_file.uid])
        self.assertIsInstance(fo_list[0], FileObject,
                              'file object has wrong type')

    def test_sanitize_extract_and_retrieve_binary(self):
        test_data = {'dummy': {'test_key': 'test_value'}}
        test_data['dummy'] = self.db_interface._extract_binaries(
            test_data, 'dummy', 'uid')
        self.assertEqual(self.db_interface.sanitize_fs.list(),
                         ['dummy_test_key_uid'], 'file not written')
        self.assertEqual(test_data['dummy']['test_key'], 'dummy_test_key_uid',
                         'new file path not set')
        test_data['dummy'] = self.db_interface._retrieve_binaries(
            test_data, 'dummy')
        self.assertEqual(test_data['dummy']['test_key'], 'test_value',
                         'value not recoverd')

    def test_get_firmware_number(self):
        result = self.db_interface.get_firmware_number()
        self.assertEqual(result, 0)

        self.db_interface_backend.add_firmware(self.test_firmware)
        result = self.db_interface.get_firmware_number(query={})
        self.assertEqual(result, 1)
        result = self.db_interface.get_firmware_number(
            query={'_id': self.test_firmware.uid})
        self.assertEqual(result, 1)

        test_fw_2 = create_test_firmware(bin_path='container/test.7z')
        self.db_interface_backend.add_firmware(test_fw_2)
        result = self.db_interface.get_firmware_number(query='{}')
        self.assertEqual(result, 2)
        result = self.db_interface.get_firmware_number(
            query={'_id': self.test_firmware.uid})
        self.assertEqual(result, 1)

    def test_get_file_object_number(self):
        result = self.db_interface.get_file_object_number()
        self.assertEqual(result, 0)

        self.db_interface_backend.add_file_object(self.test_fo)
        result = self.db_interface.get_file_object_number(
            query={}, zero_on_empty_query=False)
        self.assertEqual(result, 1)
        result = self.db_interface.get_file_object_number(
            query={'_id': self.test_fo.uid})
        self.assertEqual(result, 1)
        result = self.db_interface.get_file_object_number(
            query=json.dumps({'_id': self.test_fo.uid}))
        self.assertEqual(result, 1)
        result = self.db_interface.get_file_object_number(
            query={}, zero_on_empty_query=True)
        self.assertEqual(result, 0)
        result = self.db_interface.get_file_object_number(
            query='{}', zero_on_empty_query=True)
        self.assertEqual(result, 0)

        test_fo_2 = create_test_file_object(
            bin_path='get_files_test/testfile2')
        self.db_interface_backend.add_file_object(test_fo_2)
        result = self.db_interface.get_file_object_number(
            query={}, zero_on_empty_query=False)
        self.assertEqual(result, 2)
        result = self.db_interface.get_file_object_number(
            query={'_id': self.test_fo.uid})
        self.assertEqual(result, 1)

    def test_unpacking_lock(self):
        first_uid, second_uid = 'id1', 'id2'
        assert not self.db_interface.check_unpacking_lock(
            first_uid) and not self.db_interface.check_unpacking_lock(
                second_uid), 'locks should not be set at start'

        self.db_interface.set_unpacking_lock(first_uid)
        assert self.db_interface.check_unpacking_lock(
            first_uid), 'locks should have been set'

        self.db_interface.set_unpacking_lock(second_uid)
        assert self.db_interface.check_unpacking_lock(
            first_uid) and self.db_interface.check_unpacking_lock(
                second_uid), 'both locks should be set'

        self.db_interface.release_unpacking_lock(first_uid)
        assert not self.db_interface.check_unpacking_lock(
            first_uid) and self.db_interface.check_unpacking_lock(
                second_uid), 'lock 1 should be released, lock 2 not'

        self.db_interface.drop_unpacking_locks()
        assert not self.db_interface.check_unpacking_lock(
            second_uid), 'all locks should be dropped'

    def test_lock_is_released(self):
        self.db_interface.set_unpacking_lock(self.test_fo.uid)
        assert self.db_interface.check_unpacking_lock(
            self.test_fo.uid), 'setting lock did not work'

        self.db_interface_backend.add_object(self.test_fo)
        assert not self.db_interface.check_unpacking_lock(
            self.test_fo.uid), 'add_object should release lock'

    def test_is_firmware(self):
        assert self.db_interface.is_firmware(self.test_firmware.uid) is False

        self.db_interface_backend.add_firmware(self.test_firmware)
        assert self.db_interface.is_firmware(self.test_firmware.uid) is True

    def test_is_file_object(self):
        assert self.db_interface.is_file_object(self.test_fo.uid) is False

        self.db_interface_backend.add_file_object(self.test_fo)
        assert self.db_interface.is_file_object(self.test_fo.uid) is True
Beispiel #14
0
class TestRestStartCompare(RestTestBase):
    def setup(self):
        super().setup()
        self.db_backend = BackEndDbInterface(config=self.config)

    def teardown(self):
        self.db_backend.shutdown()
        super().teardown()

    def test_rest_start_compare_valid(self):
        test_firmware_1 = create_test_firmware(device_class='test class',
                                               device_name='test device',
                                               vendor='test vendor')
        test_firmware_2 = create_test_firmware(device_class='test class',
                                               device_name='test device',
                                               vendor='test vendor',
                                               bin_path='container/test.7z')
        self.db_backend.add_firmware(test_firmware_1)
        self.db_backend.add_firmware(test_firmware_2)

        data = {
            'uid_list': [test_firmware_1.uid, test_firmware_2.uid],
            'redo': True
        }
        rv = self.test_client.put('/rest/compare',
                                  json=data,
                                  follow_redirects=True)
        assert b'Compare started.' in rv.data

    def test_rest_start_compare_invalid_uid(self):
        rv = self.test_client.put('/rest/compare',
                                  json={'uid_list': ['123', '456']},
                                  follow_redirects=True)
        assert b'not found in database' in rv.data

    def test_rest_start_compare_invalid_data(self):
        test_firmware = create_test_firmware(device_class='test class',
                                             device_name='test device',
                                             vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.put('/rest/compare',
                                  json={'data': 'invalid data'},
                                  follow_redirects=True)
        assert rv.json['message'] == 'Input payload validation failed'
        assert 'uid_list' in rv.json['errors']
        assert '\'uid_list\' is a required property' in rv.json['errors'][
            'uid_list']

    def test_rest_get_compare_valid_not_in_db(self):
        test_firmware_1 = create_test_firmware(device_class='test class',
                                               device_name='test device',
                                               vendor='test vendor')
        test_firmware_2 = create_test_firmware(device_class='test class',
                                               device_name='test device',
                                               vendor='test vendor',
                                               bin_path='container/test.7z')
        self.db_backend.add_firmware(test_firmware_1)
        self.db_backend.add_firmware(test_firmware_2)

        rv = self.test_client.get(
            f'/rest/compare/{test_firmware_1.uid};{test_firmware_2.uid}',
            follow_redirects=True)
        assert b'Compare not found in database.' in rv.data

    def test_rest_get_compare_invalid_uid(self):
        rv = self.test_client.get(f'/rest/compare/{TEST_UID};{TEST_UID}',
                                  follow_redirects=True)
        assert b'not found in database' in rv.data

    def test_rest_get_compare_invalid_data(self):
        test_firmware = create_test_firmware(device_class='test class',
                                             device_name='test device',
                                             vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/compare', follow_redirects=True)
        assert b'The method is not allowed for the requested URL' in rv.data
Beispiel #15
0
class TestAcceptanceIoRoutes(TestAcceptanceBase):
    def setUp(self):
        super().setUp()
        self._start_backend()
        self.db_backend_interface = BackEndDbInterface(self.config)
        self.test_fw = create_test_firmware(device_name='test_fw')

    def tearDown(self):
        self.db_backend_interface.shutdown()
        self._stop_backend()
        super().tearDown()

    def test_radare_button(self):
        response = self.test_client.get(
            '/radare-view/{uid}'.format(uid=self.test_fw.uid))
        self.assertIn('200', response.status, 'radare view link failed')
        self.assertIn(b'File not found in database', response.data,
                      'radare view should fail on missing uid')

        self.db_backend_interface.add_firmware(self.test_fw)

        response = self.test_client.get(
            '/radare-view/{uid}'.format(uid=self.test_fw.uid))
        self.assertIn('200', response.status, 'radare view link failed')
        self.assertIn(b'with url: /v1/retrieve', response.data,
                      'error coming from wrong request')
        self.assertIn(b'Failed to establish a new connection', response.data,
                      'connection shall fail')

    def test_ida_download(self):
        compare_interface = CompareDbInterface(config=self.config)

        self.db_backend_interface.add_firmware(self.test_fw)

        COMPARE_RESULT['general'] = {
            'a': {
                self.test_fw.uid: 'x'
            },
            'b': {
                self.test_fw.uid: 'y'
            }
        }

        compare_interface.add_compare_result(COMPARE_RESULT)
        cid = compare_interface._calculate_compare_result_id(COMPARE_RESULT)

        response = self.test_client.get('/ida-download/{cid}'.format(cid=cid))
        self.assertIn(b'IDA database', response.data,
                      'mocked ida database not in result')

    def test_ida_download_bad_uid(self):
        compare_interface = CompareDbInterface(config=self.config)

        compare_interface.add_compare_result(COMPARE_RESULT)
        cid = compare_interface._calculate_compare_result_id(COMPARE_RESULT)

        response = self.test_client.get('/ida-download/{cid}'.format(cid=cid))
        self.assertIn(b'not found in database', response.data,
                      'endpoint should dismiss result')

    def test_pdf_download(self):
        response = self.test_client.get(
            '/pdf-download/{uid}'.format(uid=self.test_fw.uid))
        assert response.status_code == 200, 'pdf download link failed'
        assert b'File not found in database' in response.data, 'radare view should fail on missing uid'

        self.db_backend_interface.add_firmware(self.test_fw)

        response = self.test_client.get(
            '/pdf-download/{uid}'.format(uid=self.test_fw.uid))

        assert response.status_code == 200, 'pdf download failed'
        assert response.headers[
            'Content-Disposition'] == 'attachment; filename={}_analysis_report.pdf'.format(
                self.test_fw.device_name.replace(' ', '_'))
        assert get_file_type_from_binary(
            response.data)['mime'] == 'application/pdf'
Beispiel #16
0
class TestCompare:
    @classmethod
    def setup_class(cls):
        cls._config = get_config_for_testing()
        cls.mongo_server = MongoMgr(config=cls._config)

    def setup(self):
        self.db_interface = MongoInterfaceCommon(config=self._config)
        self.db_interface_backend = BackEndDbInterface(config=self._config)
        self.db_interface_compare = CompareDbInterface(config=self._config)
        self.db_interface_admin = AdminDbInterface(config=self._config)

        self.fw_one = create_test_firmware()
        self.fw_two = create_test_firmware()
        self.fw_two.set_binary(b'another firmware')
        self.compare_dict = self._create_compare_dict()
        self.compare_id = '{};{}'.format(self.fw_one.uid, self.fw_two.uid)

    def teardown(self):
        self.db_interface_compare.shutdown()
        self.db_interface_admin.shutdown()
        self.db_interface_backend.shutdown()
        self.db_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_interface.shutdown()
        gc.collect()

    @classmethod
    def teardown_class(cls):
        cls.mongo_server.shutdown()

    def _create_compare_dict(self):
        return {
            'general': {
                'hid': {
                    self.fw_one.uid: 'foo',
                    self.fw_two.uid: 'bar'
                },
                'virtual_file_path': {
                    self.fw_one.uid: 'dev_one_name',
                    self.fw_two.uid: 'dev_two_name'
                }
            },
            'plugins': {},
        }

    def test_add_and_get_compare_result(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)
        retrieved = self.db_interface_compare.get_compare_result(
            self.compare_id)
        assert retrieved['general']['virtual_file_path'][self.fw_one.uid] == 'dev_one_name',\
            'content of retrieval not correct'

    def test_get_not_existing_compare_result(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        result = self.db_interface_compare.get_compare_result(self.compare_id)
        assert result is None, 'result not none'

    def test_calculate_compare_result_id(self):
        comp_id = self.db_interface_compare._calculate_compare_result_id(
            self.compare_dict)
        assert comp_id == self.compare_id

    def test_calculate_compare_result_id__incomplete_entries(self):
        compare_dict = {
            'general': {
                'stat_1': {
                    'a': None
                },
                'stat_2': {
                    'b': None
                }
            }
        }
        comp_id = self.db_interface_compare._calculate_compare_result_id(
            compare_dict)
        assert comp_id == 'a;b'

    def test_check_objects_exist(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        assert self.db_interface_compare.check_objects_exist(
            self.fw_one.uid) is None, 'existing_object not found'
        with pytest.raises(FactCompareException):
            self.db_interface_compare.check_objects_exist(
                '{};none_existing_object'.format(self.fw_one.uid))

    def test_get_compare_result_of_nonexistent_uid(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        try:
            self.db_interface_compare.check_objects_exist(
                '{};none_existing_object'.format(self.fw_one.uid))
        except FactCompareException as exception:
            assert exception.get_message(
            ) == 'none_existing_object not found in database', 'error message not correct'

    def test_get_latest_comparisons(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        before = time()
        self.db_interface_compare.add_compare_result(self.compare_dict)
        result = self.db_interface_compare.page_compare_results(limit=10)
        for id_, hids, submission_date in result:
            assert self.fw_one.uid in hids
            assert self.fw_two.uid in hids
            assert self.fw_one.uid in id_
            assert self.fw_two.uid in id_
            assert before <= submission_date <= time()

    def test_get_latest_comparisons_removed_firmware(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)

        result = self.db_interface_compare.page_compare_results(limit=10)
        assert result != [], 'A compare result should be available'

        self.db_interface_admin.delete_firmware(self.fw_two.uid)

        result = self.db_interface_compare.page_compare_results(limit=10)

        assert result == [], 'No compare result should be available'

    def test_get_total_number_of_results(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)

        number = self.db_interface_compare.get_total_number_of_results()
        assert number == 1, 'no compare result found in database'

    @pytest.mark.parametrize('root_uid, expected_result', [
        ('the_root_uid', ['uid1', 'uid2']),
        ('some_other_uid', []),
        (None, []),
    ])
    def test_get_exclusive_files(self, root_uid, expected_result):
        compare_dict = self._create_compare_dict()
        compare_dict['plugins'] = {
            'File_Coverage': {
                'exclusive_files': {
                    'the_root_uid': ['uid1', 'uid2']
                }
            }
        }

        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(compare_dict)
        exclusive_files = self.db_interface_compare.get_exclusive_files(
            self.compare_id, root_uid)
        assert exclusive_files == expected_result
class TestCompare(unittest.TestCase):
    def setUp(self):
        self._config = get_config_for_testing()
        self.mongo_server = MongoMgr(config=self._config)
        self.db_interface = MongoInterfaceCommon(config=self._config)
        self.db_interface_backend = BackEndDbInterface(config=self._config)
        self.db_interface_compare = CompareDbInterface(config=self._config)
        self.db_interface_admin = AdminDbInterface(config=self._config)

        self.fw_one = create_test_firmware()
        self.fw_two = create_test_firmware()
        self.fw_two.set_binary(b'another firmware')
        self.compare_dict = self._create_compare_dict()

    def tearDown(self):
        self.db_interface_compare.shutdown()
        self.db_interface_admin.shutdown()
        self.db_interface_backend.shutdown()
        self.db_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_interface.shutdown()
        self.mongo_server.shutdown()
        gc.collect()

    def _create_compare_dict(self):
        comp_dict = {
            'general': {
                'hid': {
                    self.fw_one.get_uid(): 'foo',
                    self.fw_two.get_uid(): 'bar'
                }
            },
            'plugins': {}
        }
        comp_dict['general']['virtual_file_path'] = {
            self.fw_one.get_uid(): 'dev_one_name',
            self.fw_two.get_uid(): 'dev_two_name'
        }
        return comp_dict

    def test_add_and_get_compare_result(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)
        retrieved = self.db_interface_compare.get_compare_result(
            '{};{}'.format(self.fw_one.get_uid(), self.fw_two.get_uid()))
        self.assertEqual(
            retrieved['general']['virtual_file_path'][self.fw_one.get_uid()],
            'dev_one_name', 'content of retrieval not correct')

    def test_get_not_existing_compare_result(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        result = self.db_interface_compare.get_compare_result('{};{}'.format(
            self.fw_one.get_uid(), self.fw_two.get_uid()))
        self.assertIsNone(result, 'result not none')

    def test_calculate_compare_result_id(self):
        comp_id = self.db_interface_compare._calculate_compare_result_id(
            self.compare_dict)
        self.assertEqual(
            comp_id, '{};{}'.format(self.fw_one.get_uid(),
                                    self.fw_two.get_uid()))

    def test_object_existence_quick_check(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.assertIsNone(
            self.db_interface_compare.object_existence_quick_check(
                self.fw_one.get_uid()), 'existing_object not found')
        self.assertEqual(
            self.db_interface_compare.object_existence_quick_check(
                '{};none_existing_object'.format(self.fw_one.get_uid())),
            'none_existing_object not found in database',
            'error message not correct')

    def test_get_compare_result_of_none_existing_uid(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        result = self.db_interface_compare.get_compare_result(
            '{};none_existing_uid'.format(self.fw_one.get_uid()))
        self.assertEqual(result, 'none_existing_uid not found in database',
                         'no result not found error')

    def test_get_latest_comparisons(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        before = time()
        self.db_interface_compare.add_compare_result(self.compare_dict)
        result = self.db_interface_compare.page_compare_results(limit=10)
        for id, hids, submission_date in result:
            self.assertIn(self.fw_one.get_uid(), hids)
            self.assertIn(self.fw_two.get_uid(), hids)
            self.assertIn(self.fw_one.get_uid(), id)
            self.assertIn(self.fw_two.get_uid(), id)
            self.assertTrue(before <= submission_date <= time())

    def test_get_latest_comparisons_removed_firmware(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)

        result = self.db_interface_compare.page_compare_results(limit=10)
        self.assertNotEqual(result, [], 'A compare result should be available')

        self.db_interface_admin.delete_firmware(self.fw_two.uid)

        result = self.db_interface_compare.page_compare_results(limit=10)

        self.assertEqual(result, [], 'No compare result should be available')

    def test_get_total_number_of_results(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)

        number = self.db_interface_compare.get_total_number_of_results()
        self.assertEqual(number, 1, 'no compare result found in database')
Beispiel #18
0
class TestAcceptanceNormalSearch(TestAcceptanceBase):
    def setUp(self):
        super().setUp()
        self._start_backend()
        self.db_backend_interface = BackEndDbInterface(self.config)
        self.test_fw = create_test_firmware(device_name='test_fw')
        self.test_fw.release_date = '2001-02-03'
        self.db_backend_interface.add_firmware(self.test_fw)

    def tearDown(self):
        self.db_backend_interface.shutdown()
        self._stop_backend()
        super().tearDown()

    def _show_search_get(self):
        rv = self.test_client.get('/database/search')
        assert b'<h2>Search Firmware Database</h2>' in rv.data, 'search page not rendered correctly'

    def _show_browse_db(self):
        rv = self.test_client.get('/database/browse')
        assert self.test_fw.uid.encode(
        ) in rv.data, 'test firmware not found in browse database'

    def _show_browse_compare(self):
        rv = self.test_client.get('/database/browse_compare')
        assert '200' in rv.status, 'compare browsing site offline'

    def _show_search_post(self):
        data = {
            'device_class_dropdown': '',
            'file_name': '',
            'vendor': '',
            'device_name': '',
            'version': '',
            'release_date': '',
            'hash_value': ''
        }
        rv = self.test_client.post('/database/search',
                                   content_type='multipart/form-data',
                                   follow_redirects=True,
                                   data=data)
        assert self.test_fw.uid.encode(
        ) in rv.data, 'test firmware not found in empty search'
        data['file_name'] = self.test_fw.file_name
        data['vendor'] = self.test_fw.vendor
        rv = self.test_client.post('/database/search',
                                   content_type='multipart/form-data',
                                   follow_redirects=True,
                                   data=data)
        assert self.test_fw.uid.encode(
        ) in rv.data, 'test firmware not found in specific search'

    def _show_quick_search(self):
        rv = self.test_client.get('/database/quick_search?search_term=test_fw',
                                  follow_redirects=True)
        assert self.test_fw.uid.encode(
        ) in rv.data, 'test firmware not found in specific search'

    def _search_date(self):
        rv = self.test_client.get('/database/browse?date=February 2001',
                                  follow_redirects=True)
        assert self.test_fw.uid.encode(
        ) in rv.data, 'date search does not work'
        rv = self.test_client.get('/database/browse?date=February 2002',
                                  follow_redirects=True)
        assert self.test_fw.uid.encode(
        ) not in rv.data, 'date search does not work'

    def test_search(self):
        self._show_browse_db()
        self._show_browse_compare()
        self._show_search_get()
        self._show_search_post()
        self._show_quick_search()
        self._search_date()
Beispiel #19
0
class TestCompare(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._config = get_config_for_testing()
        cls.mongo_server = MongoMgr(config=cls._config)

    def setUp(self):
        self.db_interface = MongoInterfaceCommon(config=self._config)
        self.db_interface_backend = BackEndDbInterface(config=self._config)
        self.db_interface_compare = CompareDbInterface(config=self._config)
        self.db_interface_admin = AdminDbInterface(config=self._config)

        self.fw_one = create_test_firmware()
        self.fw_two = create_test_firmware()
        self.fw_two.set_binary(b'another firmware')
        self.compare_dict = self._create_compare_dict()

    def tearDown(self):
        self.db_interface_compare.shutdown()
        self.db_interface_admin.shutdown()
        self.db_interface_backend.shutdown()
        self.db_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_interface.shutdown()
        gc.collect()

    @classmethod
    def tearDownClass(cls):
        cls.mongo_server.shutdown()

    def _create_compare_dict(self):
        comp_dict = {
            'general': {
                'hid': {
                    self.fw_one.uid: 'foo',
                    self.fw_two.uid: 'bar'
                }
            },
            'plugins': {}
        }
        comp_dict['general']['virtual_file_path'] = {
            self.fw_one.uid: 'dev_one_name',
            self.fw_two.uid: 'dev_two_name'
        }
        return comp_dict

    def test_add_and_get_compare_result(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)
        retrieved = self.db_interface_compare.get_compare_result(
            '{};{}'.format(self.fw_one.uid, self.fw_two.uid))
        self.assertEqual(
            retrieved['general']['virtual_file_path'][self.fw_one.uid],
            'dev_one_name', 'content of retrieval not correct')

    def test_get_not_existing_compare_result(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        result = self.db_interface_compare.get_compare_result('{};{}'.format(
            self.fw_one.uid, self.fw_two.uid))
        self.assertIsNone(result, 'result not none')

    def test_calculate_compare_result_id(self):
        comp_id = self.db_interface_compare._calculate_compare_result_id(
            self.compare_dict)
        self.assertEqual(comp_id, '{};{}'.format(self.fw_one.uid,
                                                 self.fw_two.uid))

    def test_calculate_compare_result_id__incomplete_entries(self):
        compare_dict = {
            'general': {
                'stat_1': {
                    'a': None
                },
                'stat_2': {
                    'b': None
                }
            }
        }
        comp_id = self.db_interface_compare._calculate_compare_result_id(
            compare_dict)
        self.assertEqual('a;b', comp_id)

    def test_check_objects_exist(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        assert self.db_interface_compare.check_objects_exist(
            self.fw_one.uid) is None, 'existing_object not found'
        with pytest.raises(FactCompareException):
            self.db_interface_compare.check_objects_exist(
                '{};none_existing_object'.format(self.fw_one.uid))

    def test_get_compare_result_of_nonexistent_uid(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        try:
            self.db_interface_compare.check_objects_exist(
                '{};none_existing_object'.format(self.fw_one.uid))
        except FactCompareException as exception:
            assert exception.get_message(
            ) == 'none_existing_object not found in database', 'error message not correct'

    def test_get_latest_comparisons(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        before = time()
        self.db_interface_compare.add_compare_result(self.compare_dict)
        result = self.db_interface_compare.page_compare_results(limit=10)
        for id_, hids, submission_date in result:
            self.assertIn(self.fw_one.uid, hids)
            self.assertIn(self.fw_two.uid, hids)
            self.assertIn(self.fw_one.uid, id_)
            self.assertIn(self.fw_two.uid, id_)
            self.assertTrue(before <= submission_date <= time())

    def test_get_latest_comparisons_removed_firmware(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)

        result = self.db_interface_compare.page_compare_results(limit=10)
        self.assertNotEqual(result, [], 'A compare result should be available')

        self.db_interface_admin.delete_firmware(self.fw_two.uid)

        result = self.db_interface_compare.page_compare_results(limit=10)

        self.assertEqual(result, [], 'No compare result should be available')

    def test_get_total_number_of_results(self):
        self.db_interface_backend.add_firmware(self.fw_one)
        self.db_interface_backend.add_firmware(self.fw_two)
        self.db_interface_compare.add_compare_result(self.compare_dict)

        number = self.db_interface_compare.get_total_number_of_results()
        self.assertEqual(number, 1, 'no compare result found in database')
def _init_test_data(config: ConfigParser, tmp_dir: str):
    backend_db_interface = BackEndDbInterface(config=config)
    backend_db_interface.add_firmware(TEST_FW)
    store_binary_on_file_system(tmp_dir, TEST_FW)
    backend_db_interface.shutdown()
Beispiel #21
0
class TestStorageDbInterfaceBackend(unittest.TestCase):
    def setUp(self):
        self._config = get_config_for_testing(TMP_DIR)
        self.mongo_server = MongoMgr(config=self._config)
        self.db_interface = MongoInterfaceCommon(config=self._config)
        self.db_interface_backend = BackEndDbInterface(config=self._config)

        self.test_firmware = create_test_firmware()

        self.test_yara_match = {
            'rule': 'OpenSSH',
            'tags': [],
            'namespace': 'default',
            'strings': [(0, '$a', b'OpenSSH')],
            'meta': {
                'description': 'SSH library',
                'website': 'http://www.openssh.com',
                'open_source': True,
                'software_name': 'OpenSSH'
            },
            'matches': True
        }

        self.test_fo = create_test_file_object()

    def tearDown(self):
        self.db_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_interface_backend.shutdown()
        self.db_interface.shutdown()
        self.mongo_server.shutdown()
        TMP_DIR.cleanup()
        gc.collect()

    def _get_all_firmware_uids(self):
        uid_list = []
        tmp = self.db_interface.firmwares.find()
        for item in tmp:
            uid_list.append(item['_id'])
        return uid_list

    def test_add_firmware(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertGreater(len(self._get_all_firmware_uids()), 0,
                           'No entry added to DB')
        recoverd_firmware_entry = self.db_interface_backend.firmwares.find_one(
        )
        self.assertAlmostEqual(recoverd_firmware_entry['submission_date'],
                               time(),
                               msg='submission time not set correctly',
                               delta=5.0)

    def test_add_and_get_firmware(self):
        self.db_interface_backend.add_firmware(self.test_firmware)
        result_backend = self.db_interface_backend.get_firmware(
            self.test_firmware.get_uid())
        self.assertIsNotNone(result_backend.binary,
                             'binary not set in backend result')
        result_common = self.db_interface.get_firmware(
            self.test_firmware.get_uid())
        self.assertIsNone(result_common.binary, 'binary set in common result')
        self.assertEqual(result_common.size, 787,
                         'file size not correct in common')
        self.assertIsInstance(result_common.tags, dict,
                              'tag field type not correct')

    def test_add_and_get_file_object(self):
        self.db_interface_backend.add_file_object(self.test_fo)
        result_backend = self.db_interface_backend.get_file_object(
            self.test_fo.get_uid())
        self.assertIsNotNone(result_backend.binary,
                             'binary not set in backend result')
        result_common = self.db_interface.get_file_object(
            self.test_fo.get_uid())
        self.assertIsNone(result_common.binary, 'binary set in common result')
        self.assertEqual(result_common.size, 62,
                         'file size not correct in common')

    def test_update_firmware(self):
        first_dict = {
            'stub_plugin': {
                'result': 0
            },
            'other_plugin': {
                'field': 'day'
            }
        }
        second_dict = {'stub_plugin': {'result': 1}}

        self.test_firmware.processed_analysis = first_dict
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertEqual(
            0,
            self.db_interface.get_object(
                self.test_firmware.get_uid()).processed_analysis['stub_plugin']
            ['result'])
        self.test_firmware.processed_analysis = second_dict
        self.db_interface_backend.add_firmware(self.test_firmware)
        self.assertEqual(
            1,
            self.db_interface.get_object(
                self.test_firmware.get_uid()).processed_analysis['stub_plugin']
            ['result'])
        self.assertIn(
            'other_plugin',
            self.db_interface.get_object(
                self.test_firmware.get_uid()).processed_analysis.keys())

    def test_update_file_object(self):
        first_dict = {'other_plugin': {'result': 0}}
        second_dict = {'stub_plugin': {'result': 1}}

        self.test_fo.processed_analysis = first_dict
        self.test_fo.files_included = {'file a', 'file b'}
        self.db_interface_backend.add_file_object(self.test_fo)
        self.test_fo.processed_analysis = second_dict
        self.test_fo.files_included = {'file b', 'file c'}
        self.db_interface_backend.add_file_object(self.test_fo)
        received_object = self.db_interface.get_object(self.test_fo.get_uid())
        self.assertEqual(
            0, received_object.processed_analysis['other_plugin']['result'])
        self.assertEqual(
            1, received_object.processed_analysis['stub_plugin']['result'])
        self.assertEqual(3, len(received_object.files_included))

    def test_add_and_get_object_including_comment(self):
        comment, author, date, uid = 'this is a test comment!', 'author', '1473431685', self.test_fo.get_uid(
        )
        self.test_fo.comments.append({
            'time': str(date),
            'author': author,
            'comment': comment
        })
        self.db_interface_backend.add_file_object(self.test_fo)

        retrieved_comment = self.db_interface.get_object(uid).comments[0]
        self.assertEqual(author, retrieved_comment['author'])
        self.assertEqual(comment, retrieved_comment['comment'])
        self.assertEqual(date, retrieved_comment['time'])
Beispiel #22
0
class TestRestFirmware(RestTestBase):

    def setUp(self):
        super().setUp()
        self.db_backend = BackEndDbInterface(config=self.config)

    def tearDown(self):
        self.db_backend.shutdown()
        super().tearDown()

    def test_rest_firmware_existing(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware', follow_redirects=True)
        assert b'uids' in rv.data
        assert b'418a54d78550e8584291c96e5d6168133621f352bfc1d43cf84e81187fef4962_787' in rv.data

    def test_offset_to_empty_response(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware?offset=1', follow_redirects=True)
        assert b'uids' in rv.data
        assert b'418a54d78550e8584291c96e5d6168133621f352bfc1d43cf84e81187fef4962_787' not in rv.data

    def test_stable_response_on_bad_paging(self):
        rv = self.test_client.get('/rest/firmware?offset=Y', follow_redirects=True)
        assert b'error_message' in rv.data
        assert b'Malformed' in rv.data

    def test_rest_search_existing(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware?query={}'.format(urllib.parse.quote('{"device_class": "test class"}')), follow_redirects=True)
        assert b'uids' in rv.data
        assert b'418a54d78550e8584291c96e5d6168133621f352bfc1d43cf84e81187fef4962_787' in rv.data

    def test_rest_search_not_existing(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware?query={}'.format(urllib.parse.quote('{"device_class": "non-existing class"}')), follow_redirects=True)
        assert b'"uids": []' in rv.data

    def test_rest_upload_valid(self):
        rv = self.test_client.put('/rest/firmware', data=json.dumps(
            {
                'binary': standard_b64encode(b'test_file_content').decode(),
                'file_name': 'test_file.txt',
                'device_name': 'test_device',
                'device_class': 'test_class',
                'firmware_version': '1',
                'vendor': 'test_vendor',
                'release_date': '01.01.1970',
                'tags': '',
                'requested_analysis_systems': ['dummy']
            }
        ), follow_redirects=True)
        assert b'c1f95369a99b765e93c335067e77a7d91af3076d2d3d64aacd04e1e0a810b3ed_17' in rv.data
        assert b'"status": 0' in rv.data

    def test_rest_upload_invalid(self):
        rv = self.test_client.put('/rest/firmware', data=json.dumps(
            {
                'binary': standard_b64encode(b'test_file_content').decode(),
                'file_name': 'test_file.txt',
                'device_name': 'test_device',
                'device_class': 'test_class',
                'vendor': 'test_vendor',
                'release_date': '01.01.1970',
                'tags': '',
                'requested_analysis_systems': ['dummy']
            }
        ), follow_redirects=True)
        assert b'"error_message": "firmware_version not found"' in rv.data
        assert b'"status": 1' in rv.data

    def test_rest_download_valid(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware/{}'.format(test_firmware.uid), follow_redirects=True)

        assert b'file_type' in rv.data
        assert b'test_type' in rv.data
        assert b'unpacker' in rv.data
        assert b'used_unpack_plugin' in rv.data

    def test_rest_download_invalid_uid(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware/invalid%20uid', follow_redirects=True)

        assert b'No firmware with UID invalid uid' in rv.data

    def test_rest_download_invalid_data(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.get('/rest/firmware/', follow_redirects=True)
        assert b'404 Not Found' in rv.data

    @pytest.mark.skip(reason='Intercom not running, thus not a single plugin known')
    def test_rest_update_analysis_success(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.put('/rest/firmware/{}?update={}'.format(test_firmware.uid, urllib.parse.quote('["printable_strings"]')), follow_redirects=True)
        assert test_firmware.uid.encode() in rv.data
        assert b'"status": 0' in rv.data

    def test_rest_update_bad_query(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        rv = self.test_client.put('/rest/firmware/{}?update=not_a_list'.format(test_firmware.uid), follow_redirects=True)
        assert b'"status": 1' in rv.data
        assert b'has to be a list' in rv.data

    def test_rest_download_with_summary(self):
        test_firmware = create_test_firmware(device_class='test class', device_name='test device', vendor='test vendor')
        self.db_backend.add_firmware(test_firmware)

        request_with_summary = self.test_client.get('/rest/firmware/{}?summary=true'.format(test_firmware.uid), follow_redirects=True)
        assert test_firmware.processed_analysis['dummy']['summary'][0].encode() in request_with_summary.data
class TestStorageDbInterfaceFrontend(unittest.TestCase):
    def setUp(self):
        self._config = get_config_for_testing(TMP_DIR)
        self.mongo_server = MongoMgr(config=self._config)
        self.db_frontend_interface = FrontEndDbInterface(config=self._config)
        self.db_backend_interface = BackEndDbInterface(config=self._config)
        self.test_firmware = create_test_firmware()

    def tearDown(self):
        self.db_frontend_interface.shutdown()
        self.db_backend_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        self.db_backend_interface.shutdown()
        self.mongo_server.shutdown()
        TMP_DIR.cleanup()
        gc.collect()

    def test_get_meta_list(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        list_of_firmwares = self.db_frontend_interface.get_meta_list()
        test_output = list_of_firmwares.pop()
        self.assertEqual(test_output[1],
                         'test_vendor test_router - 0.1 (Router)',
                         'Firmware not successfully received')

    def test_get_hid_firmware(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        result = self.db_frontend_interface.get_hid(
            self.test_firmware.get_uid())
        self.assertEqual(result, 'test_vendor test_router - 0.1 (Router)',
                         'fw hid not correct')

    def test_get_hid_fo(self):
        test_fo = create_test_file_object(bin_path='get_files_test/testfile2')
        test_fo.virtual_file_path = {
            'a': ['|a|/test_file'],
            'b': ['|b|/get_files_test/testfile2']
        }
        self.db_backend_interface.add_file_object(test_fo)
        result = self.db_frontend_interface.get_hid(test_fo.get_uid(),
                                                    root_uid='b')
        self.assertEqual(result, '/get_files_test/testfile2',
                         'fo hid not correct')
        result = self.db_frontend_interface.get_hid(test_fo.get_uid())
        self.assertIsInstance(result, str, 'result is not a string')
        self.assertEqual(result[0], '/',
                         'first character not correct if no root_uid set')
        result = self.db_frontend_interface.get_hid(test_fo.get_uid(),
                                                    root_uid='c')
        self.assertEqual(
            result[0], '/',
            'first character not correct if invalid root_uid set')

    def test_get_file_name(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        result = self.db_frontend_interface.get_file_name(
            self.test_firmware.get_uid())
        self.assertEqual(result, 'test.zip', 'name not correct')

    def test_get_hid_invalid_uid(self):
        result = self.db_frontend_interface.get_hid('foo')
        self.assertEqual(result, '',
                         'invalid uid should result in empty string')

    def test_get_firmware_attribute_list(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.assertEqual(self.db_frontend_interface.get_device_class_list(),
                         ['Router'])
        self.assertEqual(self.db_frontend_interface.get_vendor_list(),
                         ['test_vendor'])
        self.assertEqual(
            self.db_frontend_interface.get_firmware_attribute_list(
                'device_name', {
                    'vendor': 'test_vendor',
                    'device_class': 'Router'
                }), ['test_router'])
        self.assertEqual(
            self.db_frontend_interface.get_firmware_attribute_list('version'),
            ['0.1'])
        self.assertEqual(self.db_frontend_interface.get_device_name_dict(),
                         {'Router': {
                             'test_vendor': ['test_router']
                         }})

    def test_get_data_for_nice_list(self):
        uid_list = [self.test_firmware.get_uid()]
        self.db_backend_interface.add_firmware(self.test_firmware)
        nice_list_data = self.db_frontend_interface.get_data_for_nice_list(
            uid_list, uid_list[0])
        self.assertEquals(
            sorted([
                'size', 'virtual_file_paths', 'uid', 'mime-type',
                'files_included'
            ]), sorted(nice_list_data[0].keys()))
        self.assertEqual(nice_list_data[0]['uid'],
                         self.test_firmware.get_uid())

    def test_generic_search(self):
        self.db_backend_interface.add_firmware(self.test_firmware)
        # str input
        result = self.db_frontend_interface.generic_search(
            '{"file_name": "test.zip"}')
        self.assertEqual(result, [self.test_firmware.get_uid()],
                         'Firmware not successfully received')
        # dict input
        result = self.db_frontend_interface.generic_search(
            {'file_name': 'test.zip'})
        self.assertEqual(result, [self.test_firmware.get_uid()],
                         'Firmware not successfully received')

    def test_all_uids_found_in_database(self):
        self.db_backend_interface.client.drop_database(
            self._config.get('data_storage', 'main_database'))
        uid_list = [self.test_firmware.get_uid()]
        self.assertFalse(
            self.db_frontend_interface.all_uids_found_in_database(uid_list))
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.assertTrue(
            self.db_frontend_interface.all_uids_found_in_database(
                [self.test_firmware.get_uid()]))

    def test_get_number_of_firmwares_in_db(self):
        self.assertEqual(
            self.db_frontend_interface.get_number_of_firmwares_in_db(), 0)
        self.db_backend_interface.add_firmware(self.test_firmware)
        self.assertEqual(
            self.db_frontend_interface.get_number_of_firmwares_in_db(), 1)

    def test_get_x_last_added_firmwares(self):
        self.assertEqual(self.db_frontend_interface.get_last_added_firmwares(),
                         [], 'empty db should result in empty list')
        test_fw_one = create_test_firmware(device_name='fw_one')
        self.db_backend_interface.add_firmware(test_fw_one)
        test_fw_two = create_test_firmware(device_name='fw_two',
                                           bin_path='container/test.7z')
        self.db_backend_interface.add_firmware(test_fw_two)
        test_fw_three = create_test_firmware(device_name='fw_three',
                                             bin_path='container/test.cab')
        self.db_backend_interface.add_firmware(test_fw_three)
        result = self.db_frontend_interface.get_last_added_firmwares(limit_x=2)
        self.assertEqual(len(result), 2, 'Number of results should be 2')
        self.assertEqual(result[0]['device_name'], 'fw_three',
                         'last firmware is not first entry')
        self.assertEqual(result[1]['device_name'], 'fw_two',
                         'second last firmware is not the second entry')

    def test_generate_file_tree_node(self):
        parent_fw = create_test_firmware()
        child_fo = create_test_file_object()
        child_fo.processed_analysis['file_type'] = {'mime': 'sometype'}
        uid = parent_fw.get_uid()
        child_fo.virtual_file_path = {
            uid: ['|{}|/folder/{}'.format(uid, child_fo.file_name)]
        }
        parent_fw.files_included = {child_fo.get_uid()}
        self.db_backend_interface.add_object(parent_fw)
        self.db_backend_interface.add_object(child_fo)
        for node in self.db_frontend_interface.generate_file_tree_node(
                uid, uid):
            self.assertIsInstance(node, FileTreeNode)
            self.assertEqual(node.name, parent_fw.file_name)
            self.assertTrue(node.has_children)
        for node in self.db_frontend_interface.generate_file_tree_node(
                child_fo.get_uid(), uid):
            self.assertIsInstance(node, FileTreeNode)
            self.assertEqual(node.name, 'folder')
            self.assertTrue(node.has_children)
            virtual_grand_child = node.get_list_of_child_nodes()[0]
            self.assertEqual(virtual_grand_child.type, 'sometype')
            self.assertFalse(virtual_grand_child.has_children)
            self.assertEqual(virtual_grand_child.name, child_fo.file_name)

    def test_get_number_of_total_matches(self):
        parent_fw = create_test_firmware()
        child_fo = create_test_file_object()
        uid = parent_fw.get_uid()
        child_fo.virtual_file_path = {
            uid: ['|{}|/folder/{}'.format(uid, child_fo.file_name)]
        }
        self.db_backend_interface.add_object(parent_fw)
        self.db_backend_interface.add_object(child_fo)
        query = '{{"$or": [{{"_id": "{}"}}, {{"_id": "{}"}}]}}'.format(
            uid, child_fo.get_uid())
        self.assertEqual(
            self.db_frontend_interface.get_number_of_total_matches(
                query, only_parent_firmwares=False), 2)
        self.assertEqual(
            self.db_frontend_interface.get_number_of_total_matches(
                query, only_parent_firmwares=True), 1)

    def test_get_other_versions_of_firmware(self):
        parent_fw1 = create_test_firmware(version='1')
        self.db_backend_interface.add_object(parent_fw1)
        parent_fw2 = create_test_firmware(version='2',
                                          bin_path='container/test.7z')
        self.db_backend_interface.add_object(parent_fw2)
        parent_fw3 = create_test_firmware(version='3',
                                          bin_path='container/test.cab')
        self.db_backend_interface.add_object(parent_fw3)

        other_versions = self.db_frontend_interface.get_other_versions_of_firmware(
            parent_fw1)
        self.assertEqual(len(other_versions), 2,
                         'wrong number of other versions')
        self.assertIn({
            '_id': parent_fw2.get_uid(),
            'version': '2'
        }, other_versions)
        self.assertIn({
            '_id': parent_fw3.get_uid(),
            'version': '3'
        }, other_versions)

        other_versions = self.db_frontend_interface.get_other_versions_of_firmware(
            parent_fw2)
        self.assertIn({
            '_id': parent_fw3.get_uid(),
            'version': '3'
        }, other_versions)
Beispiel #24
0
class TestAcceptanceNormalSearch(TestAcceptanceBase):
    def setUp(self):
        super().setUp()
        self._start_backend()
        self.db_backend_interface = BackEndDbInterface(self.config)
        self.test_fw = create_test_firmware(device_name='test_fw')
        self.db_backend_interface.add_firmware(self.test_fw)

    def tearDown(self):
        self.db_backend_interface.shutdown()
        self._stop_backend()
        super().tearDown()

    def _show_database_access_page(self):
        rv = self.test_client.get('/database')
        self.assertIn(b'<b>Search Database</b>', rv.data,
                      'database access page not rendered correctly')

    def _show_search_get(self):
        rv = self.test_client.get('/database/search')
        self.assertIn(b'<h2>Search Firmware Database</h2>', rv.data,
                      'search page not rendered correctly')

    def _show_browse_db(self):
        rv = self.test_client.get('/database/browse')
        self.assertIn(self.test_fw.get_uid().encode(), rv.data,
                      'test firmware not found in browse database')

    def _show_search_post(self):
        data = {
            'device_class_dropdown': '',
            'file_name': '',
            'vendor': '',
            'device_name': '',
            'version': '',
            'release_date': '',
            'hash_value': ''
        }
        rv = self.test_client.post('/database/search',
                                   content_type='multipart/form-data',
                                   follow_redirects=True,
                                   data=data)
        self.assertIn(self.test_fw.get_uid().encode(), rv.data,
                      'test firmware not found in empty search')
        data['file_name'] = self.test_fw.file_name
        data['vendor'] = self.test_fw.vendor
        rv = self.test_client.post('/database/search',
                                   content_type='multipart/form-data',
                                   follow_redirects=True,
                                   data=data)
        self.assertIn(self.test_fw.get_uid().encode(), rv.data,
                      'test firmware not found in specific search')

    def _show_quick_search(self):
        rv = self.test_client.get('/database/quick_search?search_term=test_fw',
                                  follow_redirects=True)
        self.assertIn(self.test_fw.get_uid().encode(), rv.data,
                      'test firmware not found in specific search')

    def test_search(self):
        self._show_database_access_page()
        self._show_browse_db()
        self._show_search_get()
        self._show_search_post()
        self._show_quick_search()