Esempio n. 1
0
    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 {}
Esempio n. 2
0
    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()
Esempio n. 3
0
    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']
Esempio n. 4
0
    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 {}
Esempio n. 5
0
    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()
Esempio n. 6
0
    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'] 
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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)
Esempio n. 10
0
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)
Esempio n. 11
0
 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
Esempio n. 12
0
 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