Beispiel #1
0
 def setUp(self):
     config = {
         'hooks': [{
             'name': 'see.test.environment_test.TestHook'
         }, {
             'name': 'see.test.environment_test.WrongHook'
         }]
     }
     self.environment = Environment(context_factory, config)
     self.environment.allocate()
Beispiel #2
0
def main():
    arguments = parse_arguments()

    context_factory = QEMUContextFactory(arguments.context)

    with Environment(context_factory, arguments.hooks) as environment:
        protocol(environment.context, arguments.sample, arguments.command)
Beispiel #3
0
def main(args):
    vm_name = args['<vm_name>']
    uri = args['--connection']
    debug = args['--debug']
    hooks_config_path = args['<plugins_configuration>']

    init_logger(debug)
    hooks_config = {}
    with open(hooks_config_path) as f:
        hooks_config = json.load(f)
    logging.info('Connect to Neo4j DB')
    graph = Graph(password=DB_PASSWORD)

    if 'configuration' not in hooks_config:
        hooks_config['configuration'] = {}

    # use default desktop ready delay if unset
    if "desktop_ready_delay" not in hooks_config['configuration']:
        hooks_config['configuration'] = DESKTOP_READY_DELAY

    # insert graph object into general hook configuration
    hooks_config['configuration']['graph'] = graph
    # insert vm_name object
    hooks_config['configuration']['domain_name'] = vm_name
    # insert debug flag
    hooks_config['configuration']['debug'] = debug

    # delete entire graph ?
    try:
        delete = hooks_config['configuration']['delete']
    except KeyError:
        pass
    else:
        if delete:
            logging.info("Deleting all nodes in graph database")
            graph.delete_all()
            # reset GraphQL IDL
            graph.run("CALL graphql.idl(null)")

    # replace existing OS ?
    os_match = OS.match(graph).where("_.name = '{}'".format(vm_name))
    try:
        replace = hooks_config['configuration']['replace']
    except KeyError:
        # assume replace = False
        if os_match.first():
            logging.info('OS already inserted, exiting')
            return
    else:
        if not replace and os_match.first():
            logging.info('OS already inserted, exiting')
            return
        elif os_match.first():
            # replace = True and an OS already exists
            logging.info('Deleting previous OS')
            graph.run(SUBGRAPH_DELETE_OS.format(vm_name))

    with QEMUDomainContextFactory(vm_name, uri) as context:
        with Environment(context, hooks_config) as environment:
            logging.info('Capturing %s', vm_name)
            protocol(environment)
Beispiel #4
0
 def test_no_context(self):
     """RuntimeError raised if the Environment has not been initialized."""
     environment = Environment(context_factory, {})
     with self.assertRaises(RuntimeError):
         context = environment.context
         context.poweron()
Beispiel #5
0
 def test_cleanup_context_error(self):
     """Errors in context cleanup are handled."""
     config = {'hooks': [{'name': 'see.test.environment_test.WrongHook'}]}
     with Environment(wrong_context_factory, config) as environment:
         context = environment.context
     self.assertTrue(context.clean)
Beispiel #6
0
class EnvironmentTest(unittest.TestCase):
    def setUp(self):
        config = {
            'hooks': [{
                'name': 'see.test.environment_test.TestHook'
            }, {
                'name': 'see.test.environment_test.WrongHook'
            }]
        }
        self.environment = Environment(context_factory, config)
        self.environment.allocate()

    def tearDown(self):
        self.environment.deallocate()

    def test_trigger_simple_event(self):
        """Environment's events are propagated to Hooks."""
        self.environment.context.trigger('event1')
        self.assertTrue(self.environment._hookmanager.hooks[0].called1)

    def test_trigger_event_async_handler(self):
        """Environment's events are propagated to Hooks."""
        self.environment.context.trigger('event1')
        hook = self.environment._hookmanager.hooks[0]
        hook.async_called.wait()
        self.assertTrue(hook.async_called.is_set())

    def test_trigger_complex_event(self):
        """Environment's events attributes are propagated to Hooks."""
        self.environment.context.trigger('event2', arg='foo')
        self.assertEqual(self.environment._hookmanager.hooks[0].event_arg,
                         'foo')

    def test_sync_cascade_event(self):
        """Events which synchronous handlers trigger other ones."""
        self.environment.context.trigger('cascade_sync')
        hook = self.environment._hookmanager.hooks[0]
        hook.async_called.wait()
        self.assertTrue(hook.async_called.is_set())
        self.assertTrue(self.environment._hookmanager.hooks[0].called1)

    def test_async_cascade_event(self):
        """Events which asynchronous handlers trigger other ones."""
        self.environment.context.trigger('cascade_async')
        hook = self.environment._hookmanager.hooks[0]
        hook.async_called.wait()
        self.assertTrue(hook.async_called.is_set())
        self.assertTrue(self.environment._hookmanager.hooks[0].called1)

    def test_trigger_handler_error(self):
        """Exceptions within synchronous handlers won't stop the execution."""
        self.environment.context.trigger('error_event')
        self.assertTrue(
            self.environment._hookmanager.hooks[1].error_handler_called)

    def test_trigger_async_handler_error(self):
        """Exceptions within asynchronous handlers won't stop the execution."""
        self.environment.context.trigger('async_error_event')
        hook = self.environment._hookmanager.hooks[1]
        hook.error_async_handler_called.wait()
        self.assertTrue(self.environment._hookmanager.hooks[1].
                        error_async_handler_called.is_set())

    def test_cleanup(self):
        """Environment's hooks are cleaned up on deallocate."""
        hook = self.environment._hookmanager.hooks[0]
        self.environment.deallocate()
        self.assertTrue(hook.clean)

    def test_cleanup_hook_error(self):
        """Errors in hooks cleanup are handled."""
        hook = self.environment._hookmanager.hooks[1]
        self.environment.deallocate()
        self.assertTrue(hook.clean)

    def test_cleanup_context_error(self):
        """Errors in context cleanup are handled."""
        config = {'hooks': [{'name': 'see.test.environment_test.WrongHook'}]}
        with Environment(wrong_context_factory, config) as environment:
            context = environment.context
        self.assertTrue(context.clean)

    def test_no_context(self):
        """RuntimeError raised if the Environment has not been initialized."""
        environment = Environment(context_factory, {})
        with self.assertRaises(RuntimeError):
            context = environment.context
            context.poweron()

    def test_unsubscribe(self):
        """Handler is unsubscribed."""
        hook = self.environment._hookmanager.hooks[0]
        hook.context.unsubscribe('event1', hook.handler1)
        self.environment.context.trigger('event1')
        self.assertFalse(hook.called1)

    def test_unsubscribe_async(self):
        """Async handler is unsubscribed."""
        hook = self.environment._hookmanager.hooks[0]
        hook.context.unsubscribe('event1', hook.async_handler)
        self.environment.context.trigger('event1')
        time.sleep(0.1)
        self.assertFalse(hook.async_called.is_set())

    def test_unsubscribe_no_such_event(self):
        """Error is raised if the given event is not registered."""
        hook = self.environment._hookmanager.hooks[0]
        with self.assertRaises(ValueError):
            hook.context.unsubscribe('event42', hook.handler1)

    def test_unsubscribe_no_such_handler(self):
        """Error is raised if the given handler is not registered."""
        hook = self.environment._hookmanager.hooks[0]
        with self.assertRaises(ValueError):
            hook.context.unsubscribe('event1', hook.cleanup)
 def setUp(self):
     config = {'hooks': [{'name': 'see.test.environment_test.TestHook'},
                         {'name': 'see.test.environment_test.WrongHook'}]}
     self.environment = Environment(context_factory, config)
     self.environment.allocate()
class EnvironmentTest(unittest.TestCase):
    def setUp(self):
        config = {'hooks': [{'name': 'see.test.environment_test.TestHook'},
                            {'name': 'see.test.environment_test.WrongHook'}]}
        self.environment = Environment(context_factory, config)
        self.environment.allocate()

    def tearDown(self):
        self.environment.deallocate()

    def test_trigger_simple_event(self):
        """Environment's events are propagated to Hooks."""
        self.environment.context.trigger('event1')
        self.assertTrue(self.environment._hookmanager.hooks[0].called1)

    def test_trigger_event_async_handler(self):
        """Environment's events are propagated to Hooks."""
        self.environment.context.trigger('event1')
        hook = self.environment._hookmanager.hooks[0]
        hook.async_called.wait()
        self.assertTrue(hook.async_called.is_set())

    def test_trigger_complex_event(self):
        """Environment's events attributes are propagated to Hooks."""
        self.environment.context.trigger('event2', arg='foo')
        self.assertEqual(self.environment._hookmanager.hooks[0].event_arg,
                         'foo')

    def test_sync_cascade_event(self):
        """Events which synchronous handlers trigger other ones."""
        self.environment.context.trigger('cascade_sync')
        hook = self.environment._hookmanager.hooks[0]
        hook.async_called.wait()
        self.assertTrue(hook.async_called.is_set())
        self.assertTrue(self.environment._hookmanager.hooks[0].called1)

    def test_async_cascade_event(self):
        """Events which asynchronous handlers trigger other ones."""
        self.environment.context.trigger('cascade_async')
        hook = self.environment._hookmanager.hooks[0]
        hook.async_called.wait()
        self.assertTrue(hook.async_called.is_set())
        self.assertTrue(self.environment._hookmanager.hooks[0].called1)

    def test_trigger_handler_error(self):
        """Exceptions within synchronous handlers won't stop the execution."""
        self.environment.context.trigger('error_event')
        self.assertTrue(self.environment._hookmanager.hooks[1].error_handler_called)

    def test_trigger_async_handler_error(self):
        """Exceptions within asynchronous handlers won't stop the execution."""
        self.environment.context.trigger('async_error_event')
        hook = self.environment._hookmanager.hooks[1]
        hook.error_async_handler_called.wait()
        self.assertTrue(self.environment._hookmanager.hooks[1].error_async_handler_called.is_set())

    def test_cleanup(self):
        """Environment's hooks are cleaned up on deallocate."""
        hook = self.environment._hookmanager.hooks[0]
        self.environment.deallocate()
        self.assertTrue(hook.clean)

    def test_cleanup_hook_error(self):
        """Errors in hooks cleanup are handled."""
        hook = self.environment._hookmanager.hooks[1]
        self.environment.deallocate()
        self.assertTrue(hook.clean)

    def test_cleanup_context_error(self):
        """Errors in context cleanup are handled."""
        config = {'hooks': [{'name': 'see.test.environment_test.WrongHook'}]}
        with Environment(wrong_context_factory, config) as environment:
            context = environment.context
        self.assertTrue(context.clean)

    def test_no_context(self):
        """RuntimeError raised if the Environment has not been initialized."""
        environment = Environment(context_factory, {})
        with self.assertRaises(RuntimeError):
            context = environment.context
            context.poweron()

    def test_unsubscribe(self):
        """Handler is unsubscribed."""
        hook = self.environment._hookmanager.hooks[0]
        hook.context.unsubscribe('event1', hook.handler1)
        self.environment.context.trigger('event1')
        self.assertFalse(hook.called1)

    def test_unsubscribe_async(self):
        """Async handler is unsubscribed."""
        hook = self.environment._hookmanager.hooks[0]
        hook.context.unsubscribe('event1', hook.async_handler)
        self.environment.context.trigger('event1')
        time.sleep(0.1)
        self.assertFalse(hook.async_called.is_set())

    def test_unsubscribe_no_such_event(self):
        """Error is raised if the given event is not registered."""
        hook = self.environment._hookmanager.hooks[0]
        with self.assertRaises(ValueError):
            hook.context.unsubscribe('event42', hook.handler1)

    def test_unsubscribe_no_such_handler(self):
        """Error is raised if the given handler is not registered."""
        hook = self.environment._hookmanager.hooks[0]
        with self.assertRaises(ValueError):
            hook.context.unsubscribe('event1', hook.cleanup)
Beispiel #9
0
def capture_main(args):
    vm_name = args['<vm_name>']
    uri = args['--connection']
    debug = args['--debug']
    hooks_config_path = args['<plugins_configuration>']

    init_logger(debug)

    # load hooks.json
    hooks_config = {}
    with open(hooks_config_path) as f:
        try:
            hooks_config = json.load(f)
        except json.JSONDecodeError:
            logging.error("Failed to parse %s: Invalid JSON",
                          hooks_config_path)
            return

    if 'configuration' not in hooks_config:
        hooks_config['configuration'] = {}

    # use default desktop ready delay if unset
    if "desktop_ready_delay" not in hooks_config['configuration']:
        hooks_config['configuration'][
            'desktop_ready_delay'] = DESKTOP_READY_DELAY

    # insert vm_name object
    hooks_config['configuration']['domain_name'] = vm_name
    # insert debug flag
    hooks_config['configuration']['debug'] = debug

    # Neo4j required ?
    neo4j = hooks_config['configuration'].get('neo4j', {})
    if neo4j.get('enabled'):
        logging.info('Connect to Neo4j DB')
        graph = Graph(password=DB_PASSWORD)
        # handle 'delete' key
        # delete entire graph ?
        delete = neo4j.get('delete')
        if delete:
            logging.info("Deleting all nodes in graph database")
            graph.delete_all()
        # handle 'replace' key
        # replace existing OS in Neo4j ?
        replace = neo4j.get('replace', False)
        os_match = OS.match(graph).where("_.name = '{}'".format(vm_name))
        if not replace and os_match.first():
            logging.info('OS %s already inserted, exiting', vm_name)
            return
        elif os_match.first():
            # replace = True and an OS already exists
            logging.info('Deleting previous OS %s', vm_name)
            graph.run(SUBGRAPH_DELETE_OS.format(vm_name))

        # init new OS node
        os_node = OS(vm_name)
        # create it already, so transactions will work in hooks
        logging.info('Creating OS node %s', os_node.name)
        graph.create(os_node)
        neo4j['OS'] = os_node
        neo4j['graph'] = graph

    # Run the protocol
    try:
        with QEMUDomainContextFactory(vm_name, uri) as context:
            with Environment(context, hooks_config) as environment:
                logging.info('Capturing %s', vm_name)
                start = timer()
                protocol(environment)
                end = timer()
                delta = timedelta(seconds=end - start)
                # remove microseconds
                duration = str(delta).split('.')[0]
                logging.info('Capture duration: %s', duration)
    except KeyboardInterrupt:
        # cleanup
        if neo4j.get('enabled'):
            logging.warning("SIGINT received")
            logging.info("cleanup: removing OS node")
            graph: Graph = neo4j.get('graph', None)
            os_node: OS = neo4j.get('OS', None)
            if graph is not None and os_node is not None:
                graph.run(SUBGRAPH_DELETE_OS.format(vm_name))

    if neo4j.get('enabled'):
        # push OS node updates
        os_node: OS = neo4j['OS']
        graph: Graph = neo4j['graph']
        graph.push(os_node)