def test_malicious_node_distributed_query_write(self, db, node, testapp): foo = NodeFactory(host_identifier='foo') q1 = DistributedQuery.create( sql= "select name, path, pid from processes where name = 'osqueryd';", node=node) q2 = DistributedQuery.create( sql= "select name, path, pid from processes where name = 'osqueryd';", node=foo) q1.update(status=DistributedQuery.PENDING) q2.update(status=DistributedQuery.PENDING) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': foo.node_key, 'queries': { q1.guid: 'bar' } }) assert not q1.result assert not q2.result resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': foo.node_key, 'queries': { q2.guid: 'bar' } }) assert q2.result
def test_malicious_node_distributed_query_write(self, db, node, testapp): foo = NodeFactory(host_identifier='foo') q1 = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';") t1 = DistributedQueryTask.create(node=node, distributed_query=q1) q2 = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';") t2 = DistributedQueryTask.create(node=foo, distributed_query=q2) t1.update(status=DistributedQueryTask.PENDING) t2.update(status=DistributedQueryTask.PENDING) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': foo.node_key, 'queries': { t1.guid: 'bar' } }) assert not q1.results assert not q2.results resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': foo.node_key, 'queries': { t2.guid: 'bar' } }) assert t2.results
def test_distributed_query_write_state_complete(self, db, node, testapp): q = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';", node=node) q.update(status=DistributedQuery.PENDING) data = [{ "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97830" }, { "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97830" }] r = DistributedQueryResult.create(data=data, distributed_query=q) q.update(status=DistributedQuery.COMPLETE) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': node.node_key, 'queries': { q.guid: '', } }) assert q.result == r assert q.result.data == data
def test_distributed_query_table_filter_status(self, db, testapp): node1 = NodeFactory(host_identifier='node1') node2 = NodeFactory(host_identifier='node2') # Create a fake query and tasks for each node q = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';") t1 = DistributedQueryTask.create(node=node1, distributed_query=q) t2 = DistributedQueryTask.create(node=node2, distributed_query=q) t1.update(status=DistributedQueryTask.PENDING) t2.update(status=DistributedQueryTask.COMPLETE) r1 = DistributedQueryResult.create(distributed_query_task=t1, distributed_query=q, columns={ 'query': 'number 1', }) r2 = DistributedQueryResult.create(distributed_query_task=t2, distributed_query=q, columns={ 'query': 'number 2', }) # Verify that only the complete one exists in the table resp = testapp.get(url_for('manage.distributed_results', distributed_id=q.id, status='complete')) assert 'number 1' not in resp.text assert 'number 2' in resp.text # Should only have one result assert 'displaying <b>1 - 1</b> of <b>1</b> complete distributed query results' in resp.text
def test_distributed_query_write_state_complete(self, db, node, testapp): q = DistributedQuery.create( sql= "select name, path, pid from processes where name = 'osqueryd';", node=node) q.update(status=DistributedQuery.PENDING) data = [{ "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97830" }, { "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97830" }] r = DistributedQueryResult.create(data=data, distributed_query=q) q.update(status=DistributedQuery.COMPLETE) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': node.node_key, 'queries': { q.guid: '', } }) assert q.result == r assert q.result.data == data
def add_distributed(): form = AddDistributedQueryForm() form.set_choices() if form.validate_on_submit(): nodes = [] if not form.nodes.data and not form.tags.data: # all nodes get this query nodes = Node.query.all() if form.nodes.data: nodes.extend( Node.query.filter(Node.node_key.in_(form.nodes.data)).all()) if form.tags.data: nodes.extend( Node.query.filter(Node.tags.any(Tag.value.in_( form.tags.data))).all()) query = DistributedQuery.create(sql=form.sql.data, description=form.description.data, not_before=form.not_before.data) for node in nodes: task = DistributedQueryTask(node=node, distributed_query=query) db.session.add(task) else: db.session.commit() return redirect(url_for('manage.distributed', status='new')) flash_errors(form) return render_template('distributed.html', form=form)
def test_distributed_query_write_state_pending(self, db, node, testapp): q = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';", node=node) q.update(status=DistributedQuery.PENDING) data = [{ "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97830" }, { "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97831" }] resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': node.node_key, 'queries': { q.guid: data, } }) assert q.status == DistributedQuery.COMPLETE assert q.results assert q.results[0].columns == data[0] assert q.results[1].columns == data[1]
def test_distributed_query_write_state_complete(self, db, node, testapp): q = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';") t = DistributedQueryTask.create(node=node, distributed_query=q) t.update(status=DistributedQueryTask.PENDING) data = [{ "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97830" }, { "name": "osqueryd", "path": "/usr/local/bin/osqueryd", "pid": "97831" }] r = DistributedQueryResult.create(columns=data[0], distributed_query=q, distributed_query_task=t) t.update(status=DistributedQueryTask.COMPLETE) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': node.node_key, 'queries': { t.guid: '', } }) assert q.results assert len(q.results) == 1 assert q.results[0] == r assert q.results[0].columns == data[0]
def test_distributed_query_read_pending(self, db, node, testapp): q = DistributedQuery.create(sql='select * from osquery_info;', node=node) q.update(status=DistributedQuery.PENDING) resp = testapp.post_json(url_for('api.distributed_read'), { 'node_key': node.node_key, }) assert not resp.json['queries']
def test_distributed_query_read_complete(self, db, node, testapp): q = DistributedQuery.create(sql='select * from osquery_info;', node=node) q.update(status=DistributedQuery.COMPLETE) resp = testapp.post_json(url_for('api.distributed_read'), { 'node_key': node.node_key, }) assert not resp.json['queries']
def test_distributed_query_read_complete(self, db, node, testapp): q = DistributedQuery.create(sql='select * from osquery_info;') t = DistributedQueryTask.create(node=node, distributed_query=q) t.update(status=DistributedQueryTask.COMPLETE) resp = testapp.post_json(url_for('api.distributed_read'), { 'node_key': node.node_key, }) assert not resp.json['queries']
def test_distributed_query_read_new(self, db, node, testapp): q = DistributedQuery.create(sql='select * from osquery_info;', node=node) assert q.status == DistributedQuery.NEW resp = testapp.post_json(url_for('api.distributed_read'), { 'node_key': node.node_key, }) assert q.status == DistributedQuery.PENDING assert q.guid in resp.json['queries'] assert resp.json['queries'][q.guid] == q.sql
def test_distributed_query_write_state_new(self, db, node, testapp): q = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';") t = DistributedQueryTask.create(node=node, distributed_query=q) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': node.node_key, 'queries': { t.guid: '', } }) assert t.status == DistributedQueryTask.NEW assert not q.results
def test_distributed_query_table_basic(self, db, node, testapp): # Create two fake queries, tasks, and fake results. q1 = DistributedQuery.create( sql="select name, path, pid from processes where name = 'osqueryd';") t1 = DistributedQueryTask.create(node=node, distributed_query=q1) q2 = DistributedQuery.create( sql="select name, path, pid from processes where name = 'otherproc';") t2 = DistributedQueryTask.create(node=node, distributed_query=q2) t1.update(status=DistributedQueryTask.PENDING) t2.update(status=DistributedQueryTask.PENDING) r1 = DistributedQueryResult.create(distributed_query_task=t1, distributed_query=q1, columns={ 'query': 'number 1', }) r2 = DistributedQueryResult.create(distributed_query_task=t2, distributed_query=q2, columns={ 'query': 'number 2', }) # Verify that the first query is there, and the second is not resp = testapp.get(url_for('manage.distributed_results', distributed_id=q1.id)) assert self.html_escape(q1.sql) in resp.text assert self.html_escape(q2.sql) not in resp.text
def test_distributed_query_write_state_new(self, db, node, testapp): q = DistributedQuery.create( sql= "select name, path, pid from processes where name = 'osqueryd';", node=node) resp = testapp.post_json(url_for('api.distributed_write'), { 'node_key': node.node_key, 'queries': { q.guid: '', } }) assert q.status == DistributedQuery.NEW assert not q.result
def add_distributed(): form = AddDistributedQueryForm() form.set_choices() if form.validate_on_submit(): nodes = [] if not form.nodes.data and not form.tags.data: # all nodes get this query nodes = Node.query.all() if form.nodes.data: nodes.extend( Node.query.filter( Node.node_key.in_(form.nodes.data) ).all() ) if form.tags.data: nodes.extend( Node.query.filter( Node.tags.any( Tag.value.in_(form.tags.data) ) ).all() ) query = DistributedQuery.create(sql=form.sql.data, description=form.description.data, not_before=form.not_before.data) for node in nodes: task = DistributedQueryTask(node=node, distributed_query=query) db.session.add(task) else: db.session.commit() return redirect(url_for('manage.distributed', status='new')) flash_errors(form) return render_template('distributed.html', form=form)
def test_distributed_query_read_not_before(self, db, node, testapp): import doorman.utils now = dt.datetime.utcnow() not_before = now + dt.timedelta(days=1) q = DistributedQuery.create(sql='select * from osquery_info;', not_before=not_before) t = DistributedQueryTask.create(node=node, distributed_query=q) assert q.not_before == not_before datetime_patcher = mock.patch.object(doorman.utils.dt, 'datetime', mock.Mock(wraps=dt.datetime)) mocked_datetime = datetime_patcher.start() mocked_datetime.utcnow.return_value = not_before - dt.timedelta(seconds=1) resp = testapp.post_json(url_for('api.distributed_read'), { 'node_key': node.node_key, }) assert not resp.json['queries'] mocked_datetime.utcnow.return_value = not_before + dt.timedelta(seconds=1) resp = testapp.post_json(url_for('api.distributed_read'), { 'node_key': node.node_key, }) assert t.status == DistributedQueryTask.PENDING assert t.timestamp == not_before + dt.timedelta(seconds=1) assert t.guid in resp.json['queries'] assert resp.json['queries'][t.guid] == q.sql datetime_patcher.stop() assert doorman.utils.dt.datetime.utcnow() != not_before