def test_adding_and_then_removing_results_in_valid_configuration(self, node, testapp): tag = Tag.create(value='foo') node.tags.append(tag) assert not node.get_config()['packs'] # should be an empty {} assert not node.get_config()['schedule'] # should be an empty {} query = Query.create(name='foobar', sql='select * from osquery_info;') query.tags.append(tag) query.save() assert node.get_config()['schedule'] assert query.name in node.get_config()['schedule'] assert not node.get_config()['packs'] # should be an empty {}
def test_valid_configuration(self, node, testapp): resp = testapp.post_json(url_for('api.configuration'), {'node_key': node.node_key}) assert resp.json['node_invalid'] is False first_config = resp.json first_config.pop('node_invalid') assert first_config == node.get_config() tag = Tag.create(value='foo') node.tags.append(tag) node.save() # test adding a tag to a query results in the query being included # for this configuration query1 = Query.create(name='bar', sql='select * from osquery_info;') query2 = Query.create(name='foobar', sql='select * from system_info;') query2.tags.append(tag) query2.save() # test adding a tag to a pack results in the pack being included # for this configuration pack = Pack.create(name='baz') pack.queries.append(query1) pack.tags.append(tag) pack.save() file_path = FilePath.create(category='foobar', target_paths=[ '/home/foobar/%%', ]) file_path.tags.append(tag) file_path.save() resp = testapp.post_json(url_for('api.configuration'), {'node_key': node.node_key}) assert resp.json['node_invalid'] is False second_config = resp.json second_config.pop('node_invalid') assert second_config != first_config assert second_config == node.get_config()
def test_config(self): node = NodeFactory(host_identifier='foo') tag = Tag.create(value='foo') node.tags.append(tag) node.save() query1 = Query.create(name='bar', sql='select * from osquery_info;') query2 = Query.create(name='foobar', sql='select * from system_info;') query2.tags.append(tag) query2.save() pack = Pack.create(name='baz') pack.queries.append(query1) pack.tags.append(tag) pack.save() file_path = FilePath.create(category='foobar', target_paths=[ '/home/foobar/%%', ]) file_path.tags.append(tag) file_path.save() assert tag in pack.tags assert tag in query2.tags assert tag in file_path.tags assert tag not in query1.tags assert query1 in pack.queries assert query2 not in pack.queries assert pack in node.packs assert query2 in node.queries assert query1 not in node.queries config = node.get_config() assert node.host_identifier == config['options']['host_identifier'] assert pack.name in config['packs'] assert query1.name in config['packs'][pack.name]['queries'] assert query1.sql == config['packs'][pack.name]['queries'][ query1.name]['query'] assert query2.name not in config['packs'] assert query2.name in config['schedule'] assert query2.sql == config['schedule'][query2.name]['query'] assert file_path.category in config['file_paths']
def test_adding_and_then_removing_results_in_valid_configuration( self, node, testapp): tag = Tag.create(value='foo') node.tags.append(tag) assert not node.get_config()['packs'] # should be an empty {} assert not node.get_config()['schedule'] # should be an empty {} query = Query.create(name='foobar', sql='select * from osquery_info;') query.tags.append(tag) query.save() assert node.get_config()['schedule'] assert query.name in node.get_config()['schedule'] assert not node.get_config()['packs'] # should be an empty {}
def test_valid_configuration(self, node, testapp): resp = testapp.post_json(url_for('api.configuration'), { 'node_key': node.node_key}) assert resp.json['node_invalid'] is False first_config = resp.json first_config.pop('node_invalid') assert first_config == node.get_config() tag = Tag.create(value='foo') node.tags.append(tag) node.save() # test adding a tag to a query results in the query being included # for this configuration query1 = Query.create(name='bar', sql='select * from osquery_info;') query2 = Query.create(name='foobar', sql='select * from system_info;') query2.tags.append(tag) query2.save() # test adding a tag to a pack results in the pack being included # for this configuration pack = Pack.create(name='baz') pack.queries.append(query1) pack.tags.append(tag) pack.save() file_path = FilePath.create(category='foobar', target_paths=[ '/home/foobar/%%', ]) file_path.tags.append(tag) file_path.save() resp = testapp.post_json(url_for('api.configuration'), { 'node_key': node.node_key}) assert resp.json['node_invalid'] is False second_config = resp.json second_config.pop('node_invalid') assert second_config != first_config assert second_config == node.get_config()
def test_config(self): node = NodeFactory(host_identifier='foo') tag = Tag.create(value='foo') node.tags.append(tag) node.save() query1 = Query.create(name='bar', sql='select * from osquery_info;') query2 = Query.create(name='foobar', sql='select * from system_info;') query2.tags.append(tag) query2.save() pack = Pack.create(name='baz') pack.queries.append(query1) pack.tags.append(tag) pack.save() file_path = FilePath.create(category='foobar', target_paths=[ '/home/foobar/%%', ]) file_path.tags.append(tag) file_path.save() assert tag in pack.tags assert tag in query2.tags assert tag in file_path.tags assert tag not in query1.tags assert query1 in pack.queries assert query2 not in pack.queries assert pack in node.packs assert query2 in node.queries assert query1 not in node.queries config = node.get_config() assert node.host_identifier == config['options']['host_identifier'] assert pack.name in config['packs'] assert query1.name in config['packs'][pack.name]['queries'] assert query1.sql == config['packs'][pack.name]['queries'][query1.name]['query'] assert query2.name not in config['packs'] assert query2.name in config['schedule'] assert query2.sql == config['schedule'][query2.name]['query'] assert file_path.category in config['file_paths']
def create_tags(*tags): values = [] existing = [] # create a set, because we haven't yet done our association_proxy in # sqlalchemy for value in (v.strip() for v in set(tags) if v.strip()): tag = Tag.query.filter(Tag.value == value).first() if not tag: values.append(Tag.create(value=value)) else: existing.append(tag) else: if values: flash( u"Created tag{0} {1}".format( 's' if len(values) > 1 else '', ', '.join(tag.value for tag in values)), 'info') return values + existing
def create_tags(*tags): values = [] existing = [] # create a set, because we haven't yet done our association_proxy in # sqlalchemy for value in (v.strip() for v in set(tags) if v.strip()): tag = Tag.query.filter(Tag.value == value).first() if not tag: values.append(Tag.create(value=value)) else: existing.append(tag) else: if values: flash(u"Created tag{0} {1}".format( 's' if len(values) > 1 else '', ', '.join(tag.value for tag in values)), 'info') return values + existing
def enroll(): ''' Enroll an endpoint with osquery. :returns: a `node_key` unique id. Additionally `node_invalid` will be true if the node failed to enroll. ''' request_json = request.get_json() if not request_json: current_app.logger.error( "%s - Request did not contain valid JSON data. This could " "be an attempt to gather information about this endpoint " "or an automated scanner.", request.remote_addr) # Return nothing return "" enroll_secret = request_json.get( current_app.config.get('DOORMAN_ENROLL_OVERRIDE', 'enroll_secret')) if not enroll_secret: current_app.logger.error( "%s - No enroll_secret provided by remote host", request.remote_addr) return jsonify(node_invalid=True) # If we pre-populate node table with a per-node enroll_secret, # let's query it now. if current_app.config.get('DOORMAN_ENROLL_SECRET_TAG_DELIMITER'): delimiter = current_app.config.get( 'DOORMAN_ENROLL_SECRET_TAG_DELIMITER') enroll_secret, _, enroll_tags = enroll_secret.partition(delimiter) enroll_tags = set( [tag.strip() for tag in enroll_tags.split(delimiter)[:10]]) else: enroll_secret, enroll_tags = enroll_secret, set() node = Node.query.filter(Node.enroll_secret == enroll_secret).first() if not node and enroll_secret not in current_app.config[ 'DOORMAN_ENROLL_SECRET']: current_app.logger.error("%s - Invalid enroll_secret %s", request.remote_addr, enroll_secret) return jsonify(node_invalid=True) host_identifier = request_json.get('host_identifier') if node and node.enrolled_on: current_app.logger.warn( "%s - %s already enrolled on %s, returning existing node_key", request.remote_addr, node, node.enrolled_on) if node.host_identifier != host_identifier: current_app.logger.info( "%s - %s changed their host_identifier to %s", request.remote_addr, node, host_identifier) node.host_identifier = host_identifier node.update(last_checkin=dt.datetime.utcnow(), last_ip=request.remote_addr) return jsonify(node_key=node.node_key, node_invalid=False) existing_node = None if host_identifier: existing_node = Node.query.filter( Node.host_identifier == host_identifier).first() if existing_node and not existing_node.enroll_secret: current_app.logger.warning( "%s - Duplicate host_identifier %s, already enrolled %s", request.remote_addr, host_identifier, existing_node.enrolled_on) if current_app.config['DOORMAN_EXPECTS_UNIQUE_HOST_ID'] is True: current_app.logger.info( "%s - Unique host identification is true, %s already enrolled " "returning existing node key %s", request.remote_addr, host_identifier, existing_node.node_key) existing_node.update(last_checkin=dt.datetime.utcnow(), last_ip=request.remote_addr) return jsonify(node_key=existing_node.node_key, node_invalid=False) now = dt.datetime.utcnow() if node: node.update(host_identifier=host_identifier, last_checkin=now, enrolled_on=now, last_ip=request.remote_addr) else: node = Node(host_identifier=host_identifier, last_checkin=now, enrolled_on=now, last_ip=request.remote_addr) enroll_tags.update( current_app.config.get('DOORMAN_ENROLL_DEFAULT_TAGS', [])) for value in sorted((t.strip() for t in enroll_tags if t)): tag = Tag.query.filter_by(value=value).first() if tag and tag not in node.tags: node.tags.append(tag) elif not tag: node.tags.append(Tag(value=value)) node.save() current_app.logger.info("%s - Enrolled new node %s", request.remote_addr, node) notify_of_node_enrollment.delay(node.to_dict()) return jsonify(node_key=node.node_key, node_invalid=False)
def enroll(): ''' Enroll an endpoint with osquery. :returns: a `node_key` unique id. Additionally `node_invalid` will be true if the node failed to enroll. ''' request_json = request.get_json() if not request_json: current_app.logger.error( "Request did not contain valid JSON data. This could be an " "attempt to gather information about this endpoint or an " "automated scanner.") # Return nothing return "" enroll_secret = request_json.get( current_app.config.get('DOORMAN_ENROLL_OVERRIDE', 'enroll_secret')) if not enroll_secret: current_app.logger.error("No enroll_secret provided by remote host %s", request.remote_addr) return jsonify(node_invalid=True) # If we pre-populate node table with a per-node enroll_secret, # let's query it now. node = Node.query.filter(Node.enroll_secret == enroll_secret).first() if not node and enroll_secret not in current_app.config[ 'DOORMAN_ENROLL_SECRET']: current_app.logger.error("Invalid enroll_secret %s", enroll_secret) return jsonify(node_invalid=True) host_identifier = request_json.get('host_identifier') if node and node.enrolled_on: current_app.logger.warn( "%s already enrolled on %s, returning " "existing node_key", node, node.enrolled_on) if node.host_identifier != host_identifier: current_app.logger.info("%s changed their host_identifier to %s", node, host_identifier) node.update(host_identifier=host_identifier) return jsonify(node_key=node.node_key, node_invalid=False) existing_node = None if host_identifier: existing_node = Node.query.filter( Node.host_identifier == host_identifier).first() if existing_node and not existing_node.enroll_secret: current_app.logger.warning( "Duplicate host_identifier %s, already enrolled %s", host_identifier, existing_node.enrolled_on) if current_app.config['DOORMAN_EXPECTS_UNIQUE_HOST_ID'] is True: current_app.logger.info( "Unique host identification is true, %s already enrolled " "returning existing node key %s", host_identifier, existing_node.node_key) return jsonify(node_key=existing_node.node_key, node_invalid=False) now = dt.datetime.utcnow() if node: node.update(host_identifier=host_identifier, last_checkin=now, enrolled_on=now) else: node = Node(host_identifier=host_identifier, last_checkin=now, enrolled_on=now) for value in current_app.config.get('DOORMAN_ENROLL_DEFAULT_TAGS', []): tag = Tag.query.filter_by(value=value).first() if tag and tag not in node.tags: node.tags.append(tag) elif not tag: node.tags.append(Tag(value=value)) node.save() current_app.logger.info("Enrolled new node %s", node) return jsonify(node_key=node.node_key, node_invalid=False)
def test_tags(self): tag = Tag.create(value='foo') node = NodeFactory(host_identifier='foo') node.tags.append(tag) node.save() assert tag in node.tags