Example #1
0
def acs():
    logger.info("Processing SAML 'acs' Response")
    db = DivvyCloudGatewayORM()
    saml_req = prepare_flask_request(request)
    auth = init_saml_auth(saml_req)
    errors = []
    not_auth_warn = False
    configured = True
    auth.process_response()
    errors = auth.get_errors()
    not_auth_warn = not auth.is_authenticated()

    if errors:
        logger.error("SAML Response Errors: %s", errors)
        return render_template(
            'index.html',
            errors=errors,
            configured=configured,
            domain=request.url_root,
            not_auth_warn=not_auth_warn
        )

    else:
        username = auth.get_nameid()
        logger.debug(
            "Attempting Authentication for NameID: %s", auth.get_nameid
        )

        try:
            session_data = db.LoginUser(username)
            logger.info("SAML: Found user with NameID")

            user_resource_id = ResourceIds.DivvyUser(user_id=session_data['user'].user_id)
            session_permissions = SessionPermissions.load_for_user(user_resource_id=user_resource_id)
            divvysession = create_session(session_permissions=session_permissions, **session_data)

            # After Success redirect to Console App
            response = redirect(
                auth.redirect_to(
                    redirect_url(
                        request_protocol(request),
                        request.host
                    )
                )
            )
            response.set_cookie('session_id', divvysession.session_id)

            return response

        except NoResultFound:
            logger.error("SAML: No User found with NameID. Create new user with SSO id as username.")
            errors.append("SAML: No User found with NameID. Create new user with SSO id as username.")

            return render_template(
                'index.html',
                errors=errors,
                configured=configured,
                domain=request.url_root,
                not_auth_warn=not_auth_warn
            )
Example #2
0
def publish_to_sqs_queue(bot, settings, matches, _non_matches):
    # Get a mapping of topic ARNs to organization service IDs
    db = DivvyCloudGatewayORM()
    org_svc_mapping = dict(
        db.session.query(DivvyDbObjects.MessageQueue.arn,
                         DivvyDbObjects.MessageQueue.organization_service_id))

    queue = db.session.query(
        DivvyDbObjects.MessageQueue.url,
        DivvyDbObjects.MessageQueue.organization_service_id).filter(
            DivvyDbObjects.MessageQueue.arn ==
            settings['message_queue_arn']).first()

    if not queue:
        raise ValueError(
            'Unable to identify this message queue within DivvyCloud')

    message_queue_arn = settings['message_queue_arn']
    region = message_queue_arn.split(':')[3]
    org_svc_id = org_svc_mapping.get(message_queue_arn)
    if not org_svc_id:
        raise ValueError('Unable to identify organization service ID')
    frontend = get_cloud_type_by_organization_service_id(org_svc_id)
    backend = frontend.get_cloud_gw(region_name=region)
    client = backend.client('sqs')

    with ScheduledEventTracker() as context:
        for resource in matches:
            event = BotEvent('hookpoint', resource, bot.bot_id, bot.name)
            message = jinja2.Template(settings.get('message', ''))
            client.send_message(QueueUrl=queue.url,
                                MessageBody=message.render(event=event,
                                                           resource=resource))
Example #3
0
def xray_encryption_configuration_type(query, db_cls, settings_config):
    db = DivvyCloudGatewayORM()
    return query.filter(db_cls.resource_id.in_(
        db.session.query(
            DivvyDbObjects.ResourceProperty.resource_id
        ).filter(
            DivvyDbObjects.ResourceProperty.name == 'custom.xray_encryption_config_type'
        ).filter(
            DivvyDbObjects.ResourceProperty.value == settings_config['type']
        )))
    def run(self):
        """
        Job implementations must implement this method to perform their work
        """
        with NewSession(DivvyCloudGatewayORM):
            db = DivvyCloudGatewayORM()

            org_services = db.session.query(
                DivvyDbObjects.OrganizationService.organization_service_id,
                DivvyDbObjects.OrganizationService.name
            ).filter(
                DivvyDbObjects.OrganizationService.cloud_type_id == 'AWS'
            ).filter(
                DivvyDbObjects.OrganizationService.status.notin_([
                    DivvyDbObjects.OrganizationService.Status.DELETE,
                    DivvyDbObjects.OrganizationService.Status.PAUSED,
                    DivvyDbObjects.OrganizationService.Status.INVALID_CREDS,
                    DivvyDbObjects.OrganizationService.Status.ASSUME_ROLE_FAIL
                ]))

            for org_service in org_services:

                logger.info('Harvesting X-Ray encryption configuration for %s',
                            org_service.name)

                frontend = get_cloud_type_by_organization_service_id(
                    org_service.organization_service_id)

                for region in frontend.get_compute_regions():
                    backend = frontend.get_cloud_gw(region_name=region)

                    client = boto3.client(
                        'xray',
                        aws_access_key_id=backend.auth_api_key,
                        aws_secret_access_key=backend.auth_secret,
                        aws_session_token=backend.session_token,
                        region_name=region)

                    encryption_type = client.get_encryption_config(
                    )['EncryptionConfig']['Type']
                    resource_id = ResourceIds.ServiceRegion(
                        organization_service_id=org_service.
                        organization_service_id,
                        region=region)

                    db.session.merge(
                        DivvyDbObjects.ResourceProperty(
                            resource_id=resource_id,
                            name='custom.xray_encryption_config_type',
                            value=encryption_type,
                            type_hint='string'))
                    db.session.commit()
Example #5
0
 def do_harvest(self):
     with NewSession(DivvyCloudGatewayORM):
         db = DivvyCloudGatewayORM()
         if ORGANIZATION_SERVICE_ID and S3_BUCKET_NAME and FILE_KEY:
             for region_name, image_ids in self.image_getter_auth().items():
                 for image_id in image_ids:
                     db.session.merge(
                         dbobjects.ValidImage(region_name=region_name,
                                              image_id=image_id))
         else:
             for region_name, image_ids in self.image_getter_unauth().items(
             ):
                 for image_id in image_ids:
                     db.session.merge(
                         dbobjects.ValidImage(region_name=region_name,
                                              image_id=image_id))
Example #6
0
    def run(self):
        start_time = datetime.utcnow()

        # Get a mapping of topic ARNs to organization service IDs
        db = DivvyCloudGatewayORM()
        org_svc_mapping = dict(
            db.session.query(
                DivvyDbObjects.NotificationTopic.arn,
                DivvyDbObjects.NotificationTopic.organization_service_id
            )
        )
        org_svc_id = org_svc_mapping.get(self.cloud_topic)
        if not org_svc_id:
            raise ValueError('Unable to identify organization service ID')
        region = self.cloud_topic.split(':')[3]
        frontend = get_cloud_type_by_organization_service_id(org_svc_id)
        backend = frontend.get_cloud_gw(region_name=region)
        client = backend.client('sns')

        try:
            params = {
                'TopicArn': self.cloud_topic,
                'Message': self.message
            }
            if self.message_attributes:
                params['MessageAttributes'] = json.loads(str(self.message_attributes))
            if self.subject:
                params['Subject'] = self.subject

            client.publish(**params)
            status = 'SUCCESS'
            result_data = None

        except Exception:
            status = 'ERROR'
            result_data = traceback.format_exc()

        self.store_event_history(
            start_time=start_time,
            finish_time=datetime.utcnow(),
            status=status,
            result_data=result_data
        )
Example #7
0
def publish_to_cloudwatch_logs(bot, settings, matches, _non_matches):
    # Get a mapping of topic ARNs to organization service IDs
    db = DivvyCloudGatewayORM()
    org_svc_mapping = dict(
        db.session.query(
            DivvyDbObjects.ServiceLogGroup.namespace_id,
            DivvyDbObjects.ServiceLogGroup.organization_service_id))
    log_group_arn = settings['log_group_arn']
    region = log_group_arn.split(':')[3]
    log_group_name = log_group_arn.split(':')[-2]
    org_svc_id = org_svc_mapping.get(log_group_arn)
    if not org_svc_id:
        raise ValueError('Unable to identify organization service ID')
    frontend = get_cloud_type_by_organization_service_id(org_svc_id)
    backend = frontend.get_cloud_gw(region_name=region)
    client = backend.client('logs')

    # Get our last sequence token
    response = client.describe_log_streams(
        logGroupName=log_group_name,
        logStreamNamePrefix=settings['stream_name'])
    upload_sequence = None
    for item in response.get('logStreams', []):
        if item['logStreamName'] == settings['stream_name']:
            upload_sequence = item['uploadSequenceToken']

    with ScheduledEventTracker() as context:
        for resource in matches:
            event = BotEvent('hookpoint', resource, bot.bot_id, bot.name)
            message = jinja2.Template(settings.get('message', ''))
            response = client.put_log_events(
                logGroupName=log_group_name,
                logStreamName=settings['stream_name'],
                logEvents=[{
                    'timestamp':
                    int(round(time.time() * 1000)),
                    'message':
                    message.render(event=event, resource=resource),
                }],
                sequenceToken=upload_sequence)

            upload_sequence = response.get('nextSequenceToken')
Example #8
0
def storage_container_with_bucket_policy(query, db_cls, settings_config):
    # Avoid circular imports
    from DivvyWorkers.Harvesters.base import CorePropertyNames
    db = DivvyCloudGatewayORM()
    subq = db.session.query(
        DivvyDbObjects.OrganizationService.organization_service_id
    ).filter(
        DivvyDbObjects.OrganizationService.resource_id.in_(
            db.session.query(
                DivvyDbObjects.ResourceProperty.resource_id
            ).filter(
                DivvyDbObjects.ResourceProperty.name == CorePropertyNames.bucket_public_policy
            ).filter(
                func.json_extract(
                    DivvyDbObjects.ResourceProperty.value,
                    '$."{0}"'.format(settings_config['policy_option'])
                ) == True
            )
        )
    )

    return query.filter(db_cls.organization_service_id.notin_(subq))
Example #9
0
def identity_resource_with_invalid_policy(query, db_cls, settings_config):
    # First we need to build a list of policy documents and iterate over them
    db = DivvyCloudGatewayORM()
    actions = [action.lower() for action in settings_config['actions']]
    resources = settings_config.get('resources', [])
    policy_resource_ids = []
    invalid_user_resource_ids = []

    for row in db.session.query(
        dbo.ServicePolicy.resource_id,
        dbo.ServicePolicyDocument.document
    ).filter(
        dbo.ServicePolicy.arn == dbo.ServicePolicyDocument.policy_arn
    ).filter(
        dbo.ServicePolicyDocument.is_default_version.is_(True)
    ).filter(
        dbo.ServicePolicy.attachment_count != 0
    ):
        if policy_contains_permissions(
            row.document, actions, row.resource_id, resources
        ):
            policy_resource_ids.append(row.resource_id)

    for row in db.session.query(
        dbo.ServiceManagedPolicy.resource_id,
        dbo.ServiceManagedPolicyDocument.document
    ).filter(
        dbo.ServiceManagedPolicy.policy_id == dbo.ServiceManagedPolicyDocument.document_id
    ).filter(
        dbo.ServiceManagedPolicyDocument.is_default_version.is_(True)
    ):
        if policy_contains_permissions(
            row.document, actions, row.resource_id, resources
        ):
            policy_resource_ids.append(row.resource_id)

    for row in db.session.query(
        db_cls.resource_id,
        db_cls.inline_policies
    ).filter(
        db_cls.inline_policies.isnot(None)
    ):
        for policy in row.inline_policies:
            if isinstance(policy, dict):
                for _policy_name, document in policy.items():  # pylint: disable=W0612
                    if policy_contains_permissions(
                        document, actions, None, resources
                    ):
                        invalid_user_resource_ids.append(row.resource_id)

    if (
        db_cls.resource_type == ResourceType.SERVICE_USER and
        settings_config.get('walk_groups') is True
    ):
        query = query.filter(or_(
            db_cls.resource_id.in_(
                db.session.query(
                    dbo.ResourceLink.left_resource_id
                ).filter(
                    dbo.ResourceLink.right_resource_id.in_(policy_resource_ids)
                )
            ),
            db_cls.resource_id.in_(invalid_user_resource_ids),
            db_cls.resource_id.in_(
                db.session.query(
                    dbo.ResourceLink.left_resource_id
                ).filter(
                    dbo.ResourceLink.right_resource_id.in_(
                        db.session.query(
                            dbo.ResourceLink.left_resource_id
                        ).filter(
                            dbo.ResourceLink.left_resource_id.like('servicegroup:%')
                        ).filter(
                            dbo.ResourceLink.right_resource_id.in_(policy_resource_ids)
                        )
                    )
                )
            )
        ))

    else:
        query = query.filter(or_(
            db_cls.resource_id.in_(
                db.session.query(
                    dbo.ResourceLink.left_resource_id
                ).filter(
                    dbo.ResourceLink.right_resource_id.in_(policy_resource_ids)
                )
            ),
            db_cls.resource_id.in_(invalid_user_resource_ids)
        ))

    return query
Example #10
0
def instance_not_running_approved_image(query, db_cls, settings_config):
    db = DivvyCloudGatewayORM()
    return query.filter(
        db_cls.image_id.notin_(db.session.query(
            dbobjects.ValidImage.image_id)))