Beispiel #1
0
def test_datastore():
  """ Tries to save garbage data to the DB """
  datastore = Datastore()
  mydict = {"fingerprint": "9d:bc:c5:f3:a6:12:9e:0b:b5:f3:3c:93:0e:32:78:80:9c:a9:ce:8c"}
  datastore.store("keypair", "us-east-1", "seg", "myname", True, mydict)
  for itemrevision in datastore.get("keypair", "us-east-1", "seg", "myname"):
    print itemrevision.__dict__
def ensure_item_has_latest_revision_id(item):
    """
    This is a function that will attempt to correct an item that does not have a latest revision id set.
    There are two outcomes that result:
    1. If there is a revision with the item id, find the latest revision, and update the item such that it
       point to that latest revision.
    2. If not -- then we will treat the item as rancid and delete it from the database.
    :param item:
    :return The item if it was fixed -- or None if it was deleted from the DB:
    """
    if not item.latest_revision_id:
        current_revision = db.session.query(ItemRevision).filter(ItemRevision.item_id == item.id)\
                            .order_by(ItemRevision.date_created.desc()).first()

        if not current_revision:
            db.session.delete(item)
            db.session.commit()

            app.logger.error("[?] Item: {name}/{tech}/{account}/{region} does NOT have a latest revision attached, "
                             "and no current revisions were located. The item has been deleted.".format(
                                name=item.name,
                                tech=item.technology.name,
                                account=item.account.name,
                                region=item.region))

            return None

        else:
            # Update the latest revision ID:
            item.latest_revision_id = current_revision.id

            # Also need to generate the hashes:
            # 1. Get the watcher class of the item:
            watcher_cls = watcher_registry[item.technology.name]
            watcher = watcher_cls(accounts=[item.account.name])
            ds = Datastore()

            # 2. Generate the hashes:
            if watcher.honor_ephemerals:
                ephemeral_paths = watcher.ephemeral_paths
            else:
                ephemeral_paths = []

            item.latest_revision_complete_hash = ds.hash_config(current_revision.config)
            item.latest_revision_durable_hash = ds.durable_hash(current_revision.config, ephemeral_paths)

            db.session.add(item)
            db.session.commit()

            app.logger.error("[?] Item: {name}/{tech}/{account}/{region} does NOT have a latest revision attached, "
                             "but a current revision was located. The item has been fixed.".format(
                                name=item.name,
                                tech=item.technology.name,
                                account=item.account.name,
                                region=item.region))

    return item
Beispiel #3
0
def ensure_item_has_latest_revision_id(item):
    """
    This is a function that will attempt to correct an item that does not have a latest revision id set.
    There are two outcomes that result:
    1. If there is a revision with the item id, find the latest revision, and update the item such that it
       point to that latest revision.
    2. If not -- then we will treat the item as rancid and delete it from the database.
    :param item:
    :return The item if it was fixed -- or None if it was deleted from the DB:
    """
    if not item.latest_revision_id:
        current_revision = db.session.query(ItemRevision).filter(ItemRevision.item_id == item.id)\
                            .order_by(ItemRevision.date_created.desc()).first()

        if not current_revision:
            db.session.delete(item)
            db.session.commit()

            app.logger.error("[?] Item: {name}/{tech}/{account}/{region} does NOT have a latest revision attached, "
                             "and no current revisions were located. The item has been deleted.".format(
                                name=item.name,
                                tech=item.technology.name,
                                account=item.account.name,
                                region=item.region))

            return None

        else:
            # Update the latest revision ID:
            item.latest_revision_id = current_revision.id

            # Also need to generate the hashes:
            # 1. Get the watcher class of the item:
            watcher_cls = watcher_registry[item.technology.name]
            watcher = watcher_cls(accounts=[item.account.name])
            ds = Datastore()

            # 2. Generate the hashes:
            if watcher.honor_ephemerals:
                ephemeral_paths = watcher.ephemeral_paths
            else:
                ephemeral_paths = []

            item.latest_revision_complete_hash = ds.hash_config(current_revision.config)
            item.latest_revision_durable_hash = ds.durable_hash(current_revision.config, ephemeral_paths)

            db.session.add(item)
            db.session.commit()

            app.logger.error("[?] Item: {name}/{tech}/{account}/{region} does NOT have a latest revision attached, "
                             "but a current revision was located. The item has been fixed.".format(
                                name=item.name,
                                tech=item.technology.name,
                                account=item.account.name,
                                region=item.region))

    return item
Beispiel #4
0
def test_datastore():
    """ Tries to save garbage data to the DB """
    datastore = Datastore()
    mydict = {
        "fingerprint":
        "9d:bc:c5:f3:a6:12:9e:0b:b5:f3:3c:93:0e:32:78:80:9c:a9:ce:8c"
    }
    datastore.store("keypair", "us-east-1", "seg", "myname", True, mydict)
    for itemrevision in datastore.get("keypair", "us-east-1", "seg", "myname"):
        print itemrevision.__dict__
    def test_save_ephemeral_changed_item(self):
        self._setup_account()

        datastore = Datastore()

        old_item = ChangeItem(index='test_index',
                              account='test_account',
                              name='item_name',
                              active=True,
                              new_config={'config': 'test1'})

        old_item.save(datastore)

        query = Item.query.filter(Technology.name == 'test_index').filter(
            Account.name == 'test_account')
        items = query.all()
        self.assertEqual(len(items), 1)
        revisions = items[0].revisions.all()
        self.assertEqual(len(revisions), 1)

        new_item = ChangeItem(index='test_index',
                              account='test_account',
                              name='item_name',
                              active=True,
                              new_config={'config': 'test2'})
        watcher = Watcher(accounts=['test_account'])
        watcher.index = 'test_index'
        watcher.honor_ephemerals = True
        watcher.ephemeral_paths = ["config"]

        watcher.find_changes(current=[new_item])
        watcher.save()

        query = Item.query.filter(Technology.name == 'test_index').filter(
            Account.name == 'test_account')
        items = query.all()
        self.assertEqual(len(items), 1)
        revisions = items[0].revisions.all()
        self.assertEqual(len(revisions), 1)
def _delete_issues(settings):
    account = Account.query.filter(Account.id == settings.account_id).first()
    tech = Technology.query.filter(Technology.id == settings.tech_id).first()
    if account and tech:
        # Report issues as fixed
        db_items = Datastore().get_all_ctype_filtered(tech=tech.name, account=account.name, include_inactive=False)
        items = []
        for item in db_items:
            new_item = ChangeItem(index=tech.name,
                                  region=item.region,
                                  account=account.name,
                                  name=item.name,
                                  arn=item.arn)
            new_item.audit_issues = []
            new_item.db_item = item
            items.append(new_item)

        for item in items:
            for issue in item.db_item.issues:
                if issue.auditor_setting_id == settings.id:
                    item.confirmed_fixed_issues.append(issue)

    db.session.delete(settings)
    def test_ensure_item_has_latest_revision_id(self):
        """
        Test that items always have a proper current revision set.  Otherwise, the item needs to be deleted.
        :return:
        """
        from security_monkey.watchers.iam.iam_role import IAMRole
        from security_monkey.watcher import ensure_item_has_latest_revision_id
        from security_monkey.datastore import Datastore

        # Stop the watcher registry from stepping on everyone's toes:
        import security_monkey.watcher
        old_watcher_registry = security_monkey.watcher.watcher_registry
        security_monkey.watcher.watcher_registry = {IAMRole.index: IAMRole}

        # Set everything up:
        self.setup_batch_db()
        watcher = IAMRole(accounts=[self.account.name])
        watcher.current_account = (self.account, 0)
        watcher.technology = self.technology

        # Test case #1: Create an item in the DB that has no current revision ID:
        no_revision_item = Item(region="us-east-1",
                                name="NOREVISION",
                                account_id=self.account.id,
                                tech_id=self.technology.id)
        db.session.add(no_revision_item)
        db.session.commit()

        assert db.session.query(Item).filter(
            Item.name == no_revision_item.name).one()

        # Should delete the item from the DB:
        result = ensure_item_has_latest_revision_id(no_revision_item)
        assert not result
        assert not db.session.query(Item).filter(
            Item.name == no_revision_item.name).first()

        # Test case #2: Create two item revisions for the given item, but don't attach them to the item.
        #               After the fixer runs, it should return the item with proper hashes and a proper
        #               link to the latest version.
        ds = Datastore()
        no_revision_item = Item(region="us-east-1",
                                name="NOREVISION",
                                account_id=self.account.id,
                                tech_id=self.technology.id)
        db.session.add(no_revision_item)
        db.session.commit()

        ir_one = ItemRevision(config=ACTIVE_CONF,
                              date_created=datetime.datetime.utcnow(),
                              item_id=no_revision_item.id)
        ir_two = ItemRevision(config=ACTIVE_CONF,
                              date_created=(datetime.datetime.utcnow() -
                                            timedelta(days=1)),
                              item_id=no_revision_item.id)

        db.session.add(ir_one)
        db.session.add(ir_two)
        db.session.commit()

        assert len(
            db.session.query(ItemRevision).filter(
                ItemRevision.item_id == no_revision_item.id).all()) == 2
        result = ensure_item_has_latest_revision_id(no_revision_item)
        assert result
        assert result.latest_revision_id == ir_one.id
        assert ds.hash_config(
            ACTIVE_CONF) == no_revision_item.latest_revision_complete_hash
        assert ds.durable_hash(
            ACTIVE_CONF, watcher.ephemeral_paths
        ) == no_revision_item.latest_revision_durable_hash

        # Undo the mock:
        security_monkey.watcher.watcher_registry = old_watcher_registry
    def pre_test_setup(self):
        ResourcePolicyAuditor(accounts=['TEST_ACCOUNT']).OBJECT_STORE.clear()
        account_type_result = AccountType(name='AWS')
        db.session.add(account_type_result)
        db.session.commit()

        # main
        account = Account(identifier="012345678910",
                          name="TEST_ACCOUNT",
                          account_type_id=account_type_result.id,
                          notes="TEST_ACCOUNT",
                          third_party=False,
                          active=True)
        # friendly
        account2 = Account(identifier="222222222222",
                           name="TEST_ACCOUNT_TWO",
                           account_type_id=account_type_result.id,
                           notes="TEST_ACCOUNT_TWO",
                           third_party=False,
                           active=True)
        # third party
        account3 = Account(identifier="333333333333",
                           name="TEST_ACCOUNT_THREE",
                           account_type_id=account_type_result.id,
                           notes="TEST_ACCOUNT_THREE",
                           third_party=True,
                           active=True)

        db.session.add(account)
        db.session.add(account2)
        db.session.add(account3)
        db.session.commit()

        datastore = Datastore()
        # S3
        datastore.store('s3',
                        'us-east-1',
                        'TEST_ACCOUNT',
                        'my-test-s3-bucket',
                        True,
                        dict(),
                        arn='arn:aws:s3:::my-test-s3-bucket')

        datastore.store('s3',
                        'us-east-1',
                        'TEST_ACCOUNT_TWO',
                        'my-test-s3-bucket-two',
                        True,
                        dict(),
                        arn='arn:aws:s3:::my-test-s3-bucket-two')

        datastore.store('s3',
                        'us-east-1',
                        'TEST_ACCOUNT_THREE',
                        'my-test-s3-bucket-three',
                        True,
                        dict(),
                        arn='arn:aws:s3:::my-test-s3-bucket-three')

        # IAM User
        datastore.store('iamuser',
                        'us-east-1',
                        'TEST_ACCOUNT',
                        'my-test-iam-user',
                        True,
                        dict(UserId='AIDA11111111111111111',
                             UserName='******'),
                        arn='arn:aws:iam::012345678910:user/my-test-iam-user')

        datastore.store(
            'iamuser',
            'us-east-1',
            'TEST_ACCOUNT_TWO',
            'my-test-iam-user-two',
            True,
            dict(UserId='AIDA22222222222222222',
                 UserName='******'),
            arn='arn:aws:iam::222222222222:user/my-test-iam-user-two')

        datastore.store(
            'iamuser',
            'us-east-1',
            'TEST_ACCOUNT_THREE',
            'my-test-iam-user-three',
            True,
            dict(UserId='AIDA33333333333333333',
                 UserName='******'),
            arn='arn:aws:iam::333333333333:user/my-test-iam-user-three')

        # IAM Role
        datastore.store('iamrole',
                        'us-east-1',
                        'TEST_ACCOUNT',
                        'my-test-iam-role',
                        True,
                        dict(RoleId='AISA11111111111111111',
                             RoleName='my-test-iam-role'),
                        arn='arn:aws:iam::012345678910:role/my-test-iam-role')

        datastore.store(
            'iamrole',
            'us-east-1',
            'TEST_ACCOUNT_TWO',
            'my-test-iam-role-two',
            True,
            dict(RoleId='AISA22222222222222222',
                 RoleName='my-test-iam-role-two'),
            arn='arn:aws:iam::222222222222:role/my-test-iam-role-two')

        datastore.store(
            'iamrole',
            'us-east-1',
            'TEST_ACCOUNT_THREE',
            'my-test-iam-role-three',
            True,
            dict(RoleId='AISA33333333333333333',
                 RoleName='my-test-iam-role-three'),
            arn='arn:aws:iam::333333333333:role/my-test-iam-role-three')

        # NAT Gateway
        datastore.store(
            'natgateway',
            'us-east-1',
            'TEST_ACCOUNT',
            'my-test-natgateway',
            True,
            dict(nat_gateway_addresses=[
                dict(public_ip='54.11.11.11', private_ip='172.16.11.11')
            ]),
            arn=None)  # natgateway has no ARN :(

        datastore.store(
            'natgateway',
            'us-east-1',
            'TEST_ACCOUNT_TWO',
            'my-test-natgateway-two',
            True,
            dict(nat_gateway_addresses=[
                dict(public_ip='54.22.22.22', private_ip='172.16.22.22')
            ]),
            arn=None)  # natgateway has no ARN :(

        datastore.store(
            'natgateway',
            'us-east-1',
            'TEST_ACCOUNT_THREE',
            'my-test-natgateway-three',
            True,
            dict(nat_gateway_addresses=[
                dict(public_ip='54.33.33.33', private_ip='172.16.33.33')
            ]),
            arn=None)  # natgateway has no ARN :(

        # VPC
        datastore.store(
            'vpc',
            'us-east-1',
            'TEST_ACCOUNT',
            'my-test-vpc',
            True,
            dict(id='vpc-11111111', cidr_block='10.1.1.1/18'),
            arn='arn:aws:ec2:us-east-1:012345678910:vpc/vpc-11111111')

        datastore.store(
            'vpc',
            'us-east-1',
            'TEST_ACCOUNT_TWO',
            'my-test-vpc-two',
            True,
            dict(id='vpc-22222222', cidr_block='10.2.2.2/18'),
            arn='arn:aws:ec2:us-east-1:222222222222:vpc/vpc-22222222')

        datastore.store(
            'vpc',
            'us-east-1',
            'TEST_ACCOUNT_THREE',
            'my-test-vpc-three',
            True,
            dict(id='vpc-33333333', cidr_block='10.3.3.3/18'),
            arn='arn:aws:ec2:us-east-1:333333333333:vpc/vpc-33333333')

        # VPC Service Endpoint (For S3 and things)
        datastore.store('endpoint',
                        'us-east-1',
                        'TEST_ACCOUNT',
                        'my-test-vpce',
                        True,
                        dict(id='vpce-11111111'),
                        arn=None)  # vpce has no ARN :(

        datastore.store('endpoint',
                        'us-east-1',
                        'TEST_ACCOUNT_TWO',
                        'my-test-vpce-two',
                        True,
                        dict(id='vpce-22222222'),
                        arn=None)  # vpce has no ARN :(

        datastore.store('endpoint',
                        'us-east-1',
                        'TEST_ACCOUNT_THREE',
                        'my-test-vpce-three',
                        True,
                        dict(id='vpce-33333333'),
                        arn=None)  # vpce has no ARN :(
    def test_ensure_item_has_latest_revision_id(self):
        """
        Test that items always have a proper current revision set.  Otherwise, the item needs to be deleted.
        :return:
        """
        from security_monkey.watchers.iam.iam_role import IAMRole
        from security_monkey.watcher import ensure_item_has_latest_revision_id
        from security_monkey.datastore import Datastore

        # Stop the watcher registry from stepping on everyone's toes:
        import security_monkey.watcher
        old_watcher_registry = security_monkey.watcher.watcher_registry
        security_monkey.watcher.watcher_registry = {IAMRole.index: IAMRole}

        # Set everything up:
        self.setup_batch_db()
        watcher = IAMRole(accounts=[self.account.name])
        watcher.current_account = (self.account, 0)
        watcher.technology = self.technology

        # Test case #1: Create an item in the DB that has no current revision ID:
        no_revision_item = Item(region="us-east-1", name="NOREVISION", account_id=self.account.id,
                                tech_id=self.technology.id)
        db.session.add(no_revision_item)
        db.session.commit()

        assert db.session.query(Item).filter(Item.name == no_revision_item.name).one()

        # Should delete the item from the DB:
        result = ensure_item_has_latest_revision_id(no_revision_item)
        assert not result
        assert not db.session.query(Item).filter(Item.name == no_revision_item.name).first()

        # Test case #2: Create two item revisions for the given item, but don't attach them to the item.
        #               After the fixer runs, it should return the item with proper hashes and a proper
        #               link to the latest version.
        ds = Datastore()
        no_revision_item = Item(region="us-east-1", name="NOREVISION", account_id=self.account.id,
                                tech_id=self.technology.id)
        db.session.add(no_revision_item)
        db.session.commit()

        ir_one = ItemRevision(config=ACTIVE_CONF, date_created=datetime.datetime.utcnow(),
                              item_id=no_revision_item.id)
        ir_two = ItemRevision(config=ACTIVE_CONF,
                              date_created=(datetime.datetime.utcnow() - timedelta(days=1)),
                              item_id=no_revision_item.id)

        db.session.add(ir_one)
        db.session.add(ir_two)
        db.session.commit()

        assert len(db.session.query(ItemRevision).filter(ItemRevision.item_id == no_revision_item.id).all()) == 2
        result = ensure_item_has_latest_revision_id(no_revision_item)
        assert result
        assert result.latest_revision_id == ir_one.id
        assert ds.hash_config(ACTIVE_CONF) == no_revision_item.latest_revision_complete_hash
        assert ds.durable_hash(ACTIVE_CONF, watcher.ephemeral_paths) == no_revision_item.latest_revision_durable_hash

        # Undo the mock:
        security_monkey.watcher.watcher_registry = old_watcher_registry