示例#1
0
def sort_vpc_flow_logs_callback(vpc_config, current_config, path, current_path,
                                flow_log_id, callback_args):
    attached_resource = current_config['ResourceId']
    if attached_resource.startswith('vpc-'):
        vpc_path = combine_paths(current_path[0:2],
                                 ['vpcs', attached_resource])
        attached_vpc = get_object_at(vpc_config, vpc_path)
        manage_dictionary(attached_vpc, 'flow_logs', [])
        if flow_log_id not in attached_vpc['flow_logs']:
            attached_vpc['flow_logs'].append(flow_log_id)
        for subnet_id in attached_vpc['subnets']:
            manage_dictionary(attached_vpc['subnets'][subnet_id], 'flow_logs',
                              [])
            if flow_log_id not in attached_vpc['subnets'][subnet_id][
                    'flow_logs']:
                attached_vpc['subnets'][subnet_id]['flow_logs'].append(
                    flow_log_id)
    elif attached_resource.startswith('subnet-'):
        all_vpcs = get_object_at(vpc_config,
                                 combine_paths(current_path[0:2], ['vpcs']))
        for vpc in all_vpcs:
            if attached_resource in all_vpcs[vpc]['subnets']:
                manage_dictionary(all_vpcs[vpc]['subnets'][attached_resource],
                                  'flow_logs', [])
                if flow_log_id not in all_vpcs[vpc]['subnets'][
                        attached_resource]['flow_logs']:
                    all_vpcs[vpc]['subnets'][attached_resource][
                        'flow_logs'].append(flow_log_id)
                break
    else:
        printError('Resource %s attached to flow logs is not handled' %
                   attached_resource)
示例#2
0
def sort_vpc_flow_logs_callback(vpc_config, current_config, path, current_path, flow_log_id, callback_args):
    attached_resource = current_config['ResourceId']
    if attached_resource.startswith('vpc-'):
        vpc_path = combine_paths(current_path[0:2], ['vpcs', attached_resource])
        try:
            attached_vpc = get_object_at(vpc_config, vpc_path)
        except Exception as e:
            printDebug('It appears that the flow log %s is attached to a resource that was previously deleted (%s).' % (flow_log_id, attached_resource))
            return
        manage_dictionary(attached_vpc, 'flow_logs', [])
        if flow_log_id not in attached_vpc['flow_logs']:
            attached_vpc['flow_logs'].append(flow_log_id)
        for subnet_id in attached_vpc['subnets']:
            manage_dictionary(attached_vpc['subnets'][subnet_id], 'flow_logs', [])
            if flow_log_id not in attached_vpc['subnets'][subnet_id]['flow_logs']:
                attached_vpc['subnets'][subnet_id]['flow_logs'].append(flow_log_id)
    elif attached_resource.startswith('subnet-'):
        all_vpcs = get_object_at(vpc_config, combine_paths(current_path[0:2], ['vpcs']))
        for vpc in all_vpcs:
            if attached_resource in all_vpcs[vpc]['subnets']:
                manage_dictionary(all_vpcs[vpc]['subnets'][attached_resource], 'flow_logs', [])
                if flow_log_id not in all_vpcs[vpc]['subnets'][attached_resource]['flow_logs']:
                    all_vpcs[vpc]['subnets'][attached_resource]['flow_logs'].append(flow_log_id)
                break
    else:
        printError('Resource %s attached to flow logs is not handled' % attached_resource)
示例#3
0
def match_security_groups_and_resources_callback(aws_config, current_config, path, current_path, resource_id, callback_args):
    service = current_path[1]
    original_resource_path = combine_paths(copy.deepcopy(current_path), [ resource_id ])
    resource = get_object_at(aws_config, original_resource_path)
    if not 'resource_id_path' in callback_args:
        resource_type = current_path[-1]
        resource_path = copy.deepcopy(current_path)
        resource_path.append(resource_id)
    else:
        resource_path = combine_paths(copy.deepcopy(current_path), callback_args['resource_id_path'])
        resource_id = resource_path[-1]
        resource_type = resource_path[-2]
    #print('Resource path: %s' % resource_path)
    #print('Resource type: %s' % resource_type)
    #print('Resource id: %s' % resource_id)
    if 'status_path' in callback_args:
        status_path = combine_paths(copy.deepcopy(original_resource_path), callback_args['status_path'])
        #print('Status path: %s' % status_path)
        resource_status = get_object_at(aws_config, status_path)
    else:
        resource_status = None
    sg_base_path = copy.deepcopy(current_path[0:6])
    sg_base_path[1] = 'ec2'
    sg_base_path.append('security_groups')
    # Issue 89 & 91 : can instances have no security group?
    try:
        try:
            sg_attribute = get_object_at(resource, callback_args['sg_list_attribute_name'])
        except:
            return
        if type(sg_attribute) != list:
            sg_attribute = [ sg_attribute ]
        for resource_sg in sg_attribute:
            if type(resource_sg) == dict:
                sg_id = resource_sg[callback_args['sg_id_attribute_name']]
            else:
                sg_id = resource_sg
            sg_path = copy.deepcopy(sg_base_path)
            sg_path.append(sg_id)
            sg = get_object_at(aws_config, sg_path)
            # Add usage information
            manage_dictionary(sg, 'used_by', {})
            manage_dictionary(sg['used_by'], service, {})
            manage_dictionary(sg['used_by'][service], 'resource_type', {})
            manage_dictionary(sg['used_by'][service]['resource_type'], resource_type, {} if resource_status else [])
            if resource_status:
                manage_dictionary(sg['used_by'][service]['resource_type'][resource_type], resource_status, [])
                if not resource_id in sg['used_by'][service]['resource_type'][resource_type][resource_status]:
                    sg['used_by'][service]['resource_type'][resource_type][resource_status].append(resource_id)
            else:
                sg['used_by'][service]['resource_type'][resource_type].append(resource_id)
    except Exception as e:
        region = current_path[3]
        vpc_id = current_path[5]
        if vpc_id == ec2_classic and resource_type == 'elbs':
            pass
        else:
            printError('Failed to parse %s in %s in %s' % (resource_type, vpc_id, region))
            printException(e)
示例#4
0
def list_ec2_network_attack_surface_callback(ec2_config, current_config, path,
                                             current_path, privateip_id,
                                             callback_args):
    if 'Association' in current_config and current_config['Association']:
        public_ip = current_config['Association']['PublicIp']
        manage_dictionary(ec2_config, 'attack_surface', {})
        manage_dictionary(ec2_config['attack_surface'], public_ip,
                          {'protocols': {}})
        for sg_info in current_config['Groups']:
            sg_id = sg_info['GroupId']
            sg_path = copy.deepcopy(current_path[0:4])
            sg_path.append('security_groups')
            sg_path.append(sg_id)
            sg_path.append('rules')
            sg_path.append('ingress')
            ingress_rules = get_object_at(ec2_config, sg_path)
            public_ip_grants = {}
            for p in ingress_rules['protocols']:
                for port in ingress_rules['protocols'][p]['ports']:
                    if 'cidrs' in ingress_rules['protocols'][p]['ports'][port]:
                        manage_dictionary(
                            ec2_config['attack_surface'][public_ip]
                            ['protocols'], p, {'ports': {}})
                        manage_dictionary(
                            ec2_config['attack_surface'][public_ip]
                            ['protocols'][p]['ports'], port, {'cidrs': []})
                        ec2_config['attack_surface'][public_ip]['protocols'][
                            p]['ports'][port]['cidrs'] += ingress_rules[
                                'protocols'][p]['ports'][port]['cidrs']
示例#5
0
def match_network_acls_and_subnets_callback(vpc_config, current_config, path,
                                            current_path, acl_id,
                                            callback_args):
    for association in current_config['Associations']:
        subnet_path = current_path[:-1] + ['subnets', association['SubnetId']]
        subnet = get_object_at(vpc_config, subnet_path)
        subnet['network_acl'] = acl_id
示例#6
0
def parse_elb_policies_callback(aws_config, current_config, path, current_path,
                                region_id, callback_args):
    region_config = get_object_at(aws_config, [
        'services',
        'elb',
    ] + current_path + [region_id])
    region_config['elb_policies'] = current_config['elb_policies']
    for policy_id in region_config['elb_policies']:
        if region_config['elb_policies'][policy_id][
                'PolicyTypeName'] != 'SSLNegotiationPolicyType':
            continue
        # protocols, options, ciphers
        policy = region_config['elb_policies'][policy_id]
        protocols = {}
        options = {}
        ciphers = {}
        for attribute in policy['PolicyAttributeDescriptions']:
            if attribute['AttributeName'] in [
                    'Protocol-SSLv3', 'Protocol-TLSv1', 'Protocol-TLSv1.1',
                    'Protocol-TLSv1.2'
            ]:
                protocols[
                    attribute['AttributeName']] = attribute['AttributeValue']
            elif attribute['AttributeName'] in ['Server-Defined-Cipher-Order']:
                options[
                    attribute['AttributeName']] = attribute['AttributeValue']
            elif attribute['AttributeName'] == 'Reference-Security-Policy':
                policy['reference_security_policy'] = attribute[
                    'AttributeValue']
            else:
                ciphers[
                    attribute['AttributeName']] = attribute['AttributeValue']
            policy['protocols'] = protocols
            policy['options'] = options
            policy['ciphers'] = ciphers
示例#7
0
def security_group_to_attack_surface(aws_config,
                                     attack_surface_config,
                                     public_ip,
                                     current_path,
                                     security_groups,
                                     listeners=[]):
    manage_dictionary(attack_surface_config, public_ip, {'protocols': {}})
    for sg_id in security_groups:
        sg_path = copy.deepcopy(current_path[0:6])
        sg_path[1] = 'ec2'
        sg_path.append('security_groups')
        sg_path.append(sg_id)
        sg_path.append('rules')
        sg_path.append('ingress')
        ingress_rules = get_object_at(aws_config, sg_path)
        public_ip_grants = {}
        for p in ingress_rules['protocols']:
            for port in ingress_rules['protocols'][p]['ports']:
                if len(listeners) == 0 and 'cidrs' in ingress_rules[
                        'protocols'][p]['ports'][port]:
                    manage_dictionary(
                        attack_surface_config[public_ip]['protocols'], p,
                        {'ports': {}})
                    manage_dictionary(
                        attack_surface_config[public_ip]['protocols'][p]
                        ['ports'], port, {'cidrs': []})
                    attack_surface_config[public_ip]['protocols'][p]['ports'][
                        port]['cidrs'] += ingress_rules['protocols'][p][
                            'ports'][port]['cidrs']
                else:
                    ports = port.split('-')
                    if len(ports) > 1:
                        port_min = int(ports[0])
                        port_max = int(ports[1])
                    else:
                        port_min = port_max = port
                    for listener in listeners:
                        listener = int(listener)
                        if listener > port_min and listener < port_max and 'cidrs' in ingress_rules[
                                'protocols'][p]['ports'][port]:
                            manage_dictionary(
                                attack_surface_config[public_ip]['protocols'],
                                p, {'ports': {}})
                            manage_dictionary(
                                attack_surface_config[public_ip]['protocols']
                                [p]['ports'], str(listener), {'cidrs': []})
                            attack_surface_config[public_ip]['protocols'][p][
                                'ports'][str(
                                    listener)]['cidrs'] += ingress_rules[
                                        'protocols'][p]['ports'][port]['cidrs']
示例#8
0
def sort_vpc_flow_logs_callback(aws_config, current_config, path, current_path, flow_log_id, callback_args):
    attached_resource = current_config['ResourceId']
    if attached_resource.startswith('vpc-'):
        vpc_path = combine_paths(current_path[0:4], ['vpcs', attached_resource])
        try:
            attached_vpc = get_object_at(aws_config, vpc_path)
        except Exception as e:
            printDebug('It appears that the flow log %s is attached to a resource that was previously deleted (%s).' % (flow_log_id, attached_resource))
            return
        manage_dictionary(attached_vpc, 'flow_logs', [])
        if flow_log_id not in attached_vpc['flow_logs']:
            attached_vpc['flow_logs'].append(flow_log_id)
        for subnet_id in attached_vpc['subnets']:
            manage_dictionary(attached_vpc['subnets'][subnet_id], 'flow_logs', [])
            if flow_log_id not in attached_vpc['subnets'][subnet_id]['flow_logs']:
                attached_vpc['subnets'][subnet_id]['flow_logs'].append(flow_log_id)
    elif attached_resource.startswith('subnet-'):
        subnet_path = combine_paths(current_path[0:4], ['vpcs', subnet_map[attached_resource]['vpc_id'], 'subnets', attached_resource])
        subnet = get_object_at(aws_config, subnet_path)
        manage_dictionary(subnet, 'flow_logs', [])
        if flow_log_id not in subnet['flow_logs']:
            subnet['flow_logs'].append(flow_log_id)
    else:
        printError('Resource %s attached to flow logs is not handled' % attached_resource)
示例#9
0
def set_emr_vpc_ids_callback(aws_config, current_config, path, current_path, vpc_id, callback_args):
    if vpc_id != 'TODO':
        return
    region = current_path[3]
    pop_list = []
    for cluster_id in current_config['clusters']:
        cluster = current_config['clusters'][cluster_id]
        sg_id = cluster['Ec2InstanceAttributes']['EmrManagedMasterSecurityGroup']
        if sg_id in sg_map:
            vpc_id = sg_map[sg_id]['vpc_id']
            pop_list.append(cluster_id)
            region_vpcs_config = get_object_at(aws_config, current_path)
            manage_dictionary(region_vpcs_config, vpc_id, {'clusters': {}})
            region_vpcs_config[vpc_id]['clusters'][cluster_id] = cluster
    for cluster_id in pop_list:
        current_config['clusters'].pop(cluster_id)
    if len(current_config['clusters']) == 0:
        callback_args['clear_list'].append(region)
示例#10
0
def set_emr_vpc_ids_callback(aws_config, current_config, path, current_path,
                             vpc_id, callback_args):
    if vpc_id != 'TODO':
        return
    region = current_path[3]
    vpc_id = sg_id = subnet_id = None
    pop_list = []
    for cluster_id in current_config['clusters']:
        cluster = current_config['clusters'][cluster_id]
        if 'EmrManagedMasterSecurityGroup' in cluster['Ec2InstanceAttributes']:
            sg_id = cluster['Ec2InstanceAttributes'][
                'EmrManagedMasterSecurityGroup']
        elif 'RequestedEc2SubnetIds' in cluster['Ec2InstanceAttributes']:
            subnet_id = cluster['Ec2InstanceAttributes'][
                'RequestedEc2SubnetIds']
        else:
            printError('Unable to determine VPC id for EMR cluster %s' %
                       str(cluster_id))
            continue
        if sg_id in sg_map:
            vpc_id = sg_map[sg_id]['vpc_id']
            pop_list.append(cluster_id)
        else:
            sid_found = False
            if subnet_id:
                for sid in subnet_id:
                    if sid in subnet_map:
                        vpc_id = subnet_map[sid]['vpc_id']
                        pop_list.append(cluster_id)
                        sid_found = True
            if not sid_found:
                printError('Unable to determine VPC id for %s' %
                           (str(subnet_id) if subnet_id else str(sg_id)))
                continue
        if vpc_id:
            region_vpcs_config = get_object_at(aws_config, current_path)
            manage_dictionary(region_vpcs_config, vpc_id, {'clusters': {}})
            region_vpcs_config[vpc_id]['clusters'][cluster_id] = cluster
    for cluster_id in pop_list:
        current_config['clusters'].pop(cluster_id)
    if len(current_config['clusters']) == 0:
        callback_args['clear_list'].append(region)
示例#11
0
def security_group_to_attack_surface(aws_config, attack_surface_config, public_ip, current_path, security_groups, listeners = []):
        manage_dictionary(attack_surface_config, public_ip, {'protocols': {}})
        for sg_id in security_groups:
            sg_path = copy.deepcopy(current_path[0:6])
            sg_path[1] = 'ec2'
            sg_path.append('security_groups')
            sg_path.append(sg_id)
            sg_path.append('rules')
            sg_path.append('ingress')
            ingress_rules = get_object_at(aws_config, sg_path)
            if 'protocols' in ingress_rules:
                for p in ingress_rules['protocols']:
                    for port in ingress_rules['protocols'][p]['ports']:
                      if len(listeners) == 0 and 'cidrs' in ingress_rules['protocols'][p]['ports'][port]:
                          manage_dictionary(attack_surface_config[public_ip]['protocols'],
                                            p,
                                            {'ports': {}})
                          manage_dictionary(attack_surface_config[public_ip]['protocols'][p]['ports'],
                                            port,
                                            {'cidrs': []})
                          attack_surface_config[public_ip]['protocols'][p]['ports'][port]['cidrs'] += \
                              ingress_rules['protocols'][p]['ports'][port]['cidrs']
                      else:
                        ports = port.split('-')
                        if len(ports) > 1:
                            port_min = int(ports[0])
                            port_max = int(ports[1])
                        else:
                            port_min = port_max = port
                        for listener in listeners:
                            listener = int(listener)
                            if listener > port_min and listener < port_max and \
                                    'cidrs' in ingress_rules['protocols'][p]['ports'][port]:
                                manage_dictionary(attack_surface_config[public_ip]['protocols'],
                                                  p,
                                                  {'ports': {}})
                                manage_dictionary(attack_surface_config[public_ip]['protocols'][p]['ports'],
                                                  str(listener),
                                                  {'cidrs': []})
                                attack_surface_config[public_ip]['protocols'][p]['ports'][str(listener)]['cidrs'] += \
                                    ingress_rules['protocols'][p]['ports'][port]['cidrs']
示例#12
0
def parse_elb_policies_callback(aws_config, current_config, path, current_path, region_id, callback_args):
    region_config = get_object_at(aws_config, [ 'services', 'elb', ] + current_path + [ region_id ])
    region_config['elb_policies'] = current_config['elb_policies']
    for policy_id in region_config['elb_policies']:
        if region_config['elb_policies'][policy_id]['PolicyTypeName'] != 'SSLNegotiationPolicyType':
            continue
        # protocols, options, ciphers
        policy = region_config['elb_policies'][policy_id]
        protocols = {}
        options = {}
        ciphers = {}
        for attribute in policy['PolicyAttributeDescriptions']:
            if attribute['AttributeName'] in [ 'Protocol-SSLv3', 'Protocol-TLSv1', 'Protocol-TLSv1.1', 'Protocol-TLSv1.2' ]:
                protocols[attribute['AttributeName']] = attribute['AttributeValue']
            elif attribute['AttributeName'] in [ 'Server-Defined-Cipher-Order' ]:
                options[attribute['AttributeName']] = attribute['AttributeValue']
            elif attribute['AttributeName'] == 'Reference-Security-Policy':
                policy['reference_security_policy'] = attribute['AttributeValue']
            else:
                ciphers[attribute['AttributeName']] = attribute['AttributeValue']
            policy['protocols'] = protocols
            policy['options'] = options
            policy['ciphers'] = ciphers
示例#13
0
def set_emr_vpc_ids_callback(aws_config, current_config, path, current_path, vpc_id, callback_args):
    if vpc_id != 'TODO':
        return
    region = current_path[3]
    vpc_id = sg_id = subnet_id = None
    pop_list = []
    for cluster_id in current_config['clusters']:
        cluster = current_config['clusters'][cluster_id]
        if 'EmrManagedMasterSecurityGroup' in cluster['Ec2InstanceAttributes']:
            sg_id = cluster['Ec2InstanceAttributes']['EmrManagedMasterSecurityGroup']
        elif 'RequestedEc2SubnetIds' in cluster['Ec2InstanceAttributes']:
            subnet_id = cluster['Ec2InstanceAttributes']['RequestedEc2SubnetIds']
        else:
            printError('Unable to determine VPC id for EMR cluster %s' % str(cluster_id))
            continue
        if sg_id in sg_map:
            vpc_id = sg_map[sg_id]['vpc_id']
            pop_list.append(cluster_id)
        else:
            sid_found = False
            if subnet_id:
                for sid in subnet_id:
                    if sid in subnet_map:
                        vpc_id = subnet_map[sid]['vpc_id']
                        pop_list.append(cluster_id)
                        sid_found = True
            if not sid_found:
                printError('Unable to determine VPC id for %s' % (str(subnet_id) if subnet_id else str(sg_id)))
                continue
        if vpc_id:
            region_vpcs_config = get_object_at(aws_config, current_path)
            manage_dictionary(region_vpcs_config, vpc_id, {'clusters': {}})
            region_vpcs_config[vpc_id]['clusters'][cluster_id] = cluster
    for cluster_id in pop_list:
        current_config['clusters'].pop(cluster_id)
    if len(current_config['clusters']) == 0:
        callback_args['clear_list'].append(region)
示例#14
0
def match_security_groups_and_resources_callback(aws_config, current_config,
                                                 path, current_path,
                                                 resource_id, callback_args):
    service = current_path[1]
    original_resource_path = combine_paths(copy.deepcopy(current_path),
                                           [resource_id])
    resource = get_object_at(aws_config, original_resource_path)
    if not 'resource_id_path' in callback_args:
        resource_type = current_path[-1]
        resource_path = copy.deepcopy(current_path)
        resource_path.append(resource_id)
    else:
        resource_path = combine_paths(copy.deepcopy(current_path),
                                      callback_args['resource_id_path'])
        resource_id = resource_path[-1]
        resource_type = resource_path[-2]
    if 'status_path' in callback_args:
        status_path = combine_paths(copy.deepcopy(original_resource_path),
                                    callback_args['status_path'])
        resource_status = get_object_at(aws_config,
                                        status_path).replace('.', '_')
    else:
        resource_status = None
    unknown_vpc_id = True if current_path[4] != 'vpcs' else False
    # Issue 89 & 91 : can instances have no security group?
    try:
        try:
            sg_attribute = get_object_at(
                resource, callback_args['sg_list_attribute_name'])
        except:
            return
        if type(sg_attribute) != list:
            sg_attribute = [sg_attribute]
        for resource_sg in sg_attribute:
            if type(resource_sg) == dict:
                sg_id = resource_sg[callback_args['sg_id_attribute_name']]
            else:
                sg_id = resource_sg
            if unknown_vpc_id:
                vpc_id = sg_map[sg_id]['vpc_id']
                sg_base_path = copy.deepcopy(current_path[0:4])
                sg_base_path[1] = 'ec2'
                sg_base_path = sg_base_path + [
                    'vpcs', vpc_id, 'security_groups'
                ]
            else:
                sg_base_path = copy.deepcopy(current_path[0:6])
                sg_base_path[1] = 'ec2'
                sg_base_path.append('security_groups')
            sg_path = copy.deepcopy(sg_base_path)
            sg_path.append(sg_id)
            sg = get_object_at(aws_config, sg_path)
            # Add usage information
            manage_dictionary(sg, 'used_by', {})
            manage_dictionary(sg['used_by'], service, {})
            manage_dictionary(sg['used_by'][service], 'resource_type', {})
            manage_dictionary(sg['used_by'][service]['resource_type'],
                              resource_type, {} if resource_status else [])
            if resource_status:
                manage_dictionary(
                    sg['used_by'][service]['resource_type'][resource_type],
                    resource_status, [])
                if not resource_id in sg['used_by'][service]['resource_type'][
                        resource_type][resource_status]:
                    sg['used_by'][service]['resource_type'][resource_type][
                        resource_status].append(resource_id)
            else:
                sg['used_by'][service]['resource_type'][resource_type].append(
                    resource_id)
    except Exception as e:
        if resource_type in ['elbs', 'functions']:
            pass
        else:
            region = current_path[3]
            vpc_id = current_path[5]
            if vpc_id == ec2_classic:
                pass
            else:
                printError('Failed to parse %s in %s in %s' %
                           (resource_type, vpc_id, region))
                printException(e)
示例#15
0
def sort_elbs_callback(aws_config, current_config, path, current_path, elb_id,
                       callback_args):
    vpc_config = get_object_at(aws_config,
                               ['services', 'ec2'] + current_path[:-1])
    manage_dictionary(vpc_config, 'elbs', {})
    vpc_config['elbs'][elb_id] = current_config
示例#16
0
def process_metadata_callbacks(aws_config):
    """
    Iterates through each type of resource and, when callbacks have been
    configured in the config metadata, recurse through each resource and calls
    each callback.

    :param aws_config:                  The entire AWS configuration object

    :return:                            None
    """
    for service_group in aws_config['metadata']:
        for service in aws_config['metadata'][service_group]:
            if service == 'summaries':
                continue
            # Reset external attack surface
            if 'summaries' in aws_config['metadata'][service_group][service]:
                for summary in aws_config['metadata'][service_group][service]['summaries']:
                    if summary == 'external attack surface' and service in aws_config['services'] and 'external_attack_surface' in aws_config['services'][service]:
                        aws_config['services'][service].pop('external_attack_surface')
            # Reset all global summaries
            if 'service_groups' in aws_config:
                aws_config.pop('service_groups')
            # Resources
            for resource_type in aws_config['metadata'][service_group][service]['resources']:
                if 'callbacks' in aws_config['metadata'][service_group][service]['resources'][resource_type]:
                    current_path = [ 'services', service ]
                    target_path = aws_config['metadata'][service_group][service]['resources'][resource_type]['path'].replace('.id', '').split('.')[2:]
                    callbacks = aws_config['metadata'][service_group][service]['resources'][resource_type]['callbacks']
                    new_go_to_and_do(aws_config, get_object_at(aws_config, current_path), target_path, current_path, callbacks)
            # Summaries
            if 'summaries' in aws_config['metadata'][service_group][service]:
              for summary in aws_config['metadata'][service_group][service]['summaries']:
                if 'callbacks' in aws_config['metadata'][service_group][service]['summaries'][summary]:
                    current_path = [ 'services', service ]
                    for callback in aws_config['metadata'][service_group][service]['summaries'][summary]['callbacks']:
                        callback_name = callback[0]
                        callback_args = copy.deepcopy(callback[1])
                        target_path = callback_args.pop('path').replace('.id', '').split('.')[2:]
                        callbacks = [ [callback_name, callback_args] ]
                        new_go_to_and_do(aws_config, get_object_at(aws_config, current_path), target_path, current_path, callbacks)
    # Group-level summaries
    for service_group in aws_config['metadata']:
        if 'summaries' in aws_config['metadata'][service_group]:
            for summary in aws_config['metadata'][service_group]['summaries']:
                    current_path = [ 'services', service ]
                    for callback in aws_config['metadata'][service_group]['summaries'][summary]['callbacks']:
                        callback_name = callback[0]
                        callback_args = copy.deepcopy(callback[1])
                        target_path = aws_config['metadata'][service_group]['summaries'][summary]['path'].split('.')
                        target_object = aws_config
                        for p in target_path:
                            manage_dictionary(target_object, p, {})
                            target_object = target_object[p]
                        if callback_name == 'merge':
                            for service in aws_config['metadata'][service_group]:
                                if service == 'summaries':
                                    continue
                                if 'summaries' in aws_config['metadata'][service_group][service] and summary in aws_config['metadata'][service_group][service]['summaries']:
                                    try:
                                        source = get_object_at(aws_config, aws_config['metadata'][service_group][service]['summaries'][summary]['path'].split('.'))
                                    except:
                                        source = {}
                                    target_object.update(source)

    return None
示例#17
0
def match_security_groups_and_resources_callback(aws_config, current_config, path, current_path, resource_id, callback_args):
    service = current_path[1]
    original_resource_path = combine_paths(copy.deepcopy(current_path), [ resource_id ])
    resource = get_object_at(aws_config, original_resource_path)
    if not 'resource_id_path' in callback_args:
        resource_type = current_path[-1]
        resource_path = copy.deepcopy(current_path)
        resource_path.append(resource_id)
    else:
        resource_path = combine_paths(copy.deepcopy(current_path), callback_args['resource_id_path'])
        resource_id = resource_path[-1]
        resource_type = resource_path[-2]
    if 'status_path' in callback_args:
        status_path = combine_paths(copy.deepcopy(original_resource_path), callback_args['status_path'])
        resource_status = get_object_at(aws_config, status_path).replace('.', '_')
    else:
        resource_status = None
    unknown_vpc_id = True if current_path[4] != 'vpcs' else False
    # Issue 89 & 91 : can instances have no security group?
    try:
        try:
            sg_attribute = get_object_at(resource, callback_args['sg_list_attribute_name'])
        except:
            return
        if type(sg_attribute) != list:
            sg_attribute = [ sg_attribute ]
        for resource_sg in sg_attribute:
            if type(resource_sg) == dict:
                sg_id = resource_sg[callback_args['sg_id_attribute_name']]
            else:
                sg_id = resource_sg
            if unknown_vpc_id:
                vpc_id = sg_map[sg_id]['vpc_id']
                sg_base_path = copy.deepcopy(current_path[0:4])
                sg_base_path[1] = 'ec2'
                sg_base_path = sg_base_path + [ 'vpcs', vpc_id, 'security_groups' ]
            else:
                sg_base_path = copy.deepcopy(current_path[0:6])
                sg_base_path[1] = 'ec2'
                sg_base_path.append('security_groups')
            sg_path = copy.deepcopy(sg_base_path)
            sg_path.append(sg_id)
            sg = get_object_at(aws_config, sg_path)
            # Add usage information
            manage_dictionary(sg, 'used_by', {})
            manage_dictionary(sg['used_by'], service, {})
            manage_dictionary(sg['used_by'][service], 'resource_type', {})
            manage_dictionary(sg['used_by'][service]['resource_type'], resource_type, {} if resource_status else [])
            if resource_status:
                manage_dictionary(sg['used_by'][service]['resource_type'][resource_type], resource_status, [])
                if not resource_id in sg['used_by'][service]['resource_type'][resource_type][resource_status]:
                    sg['used_by'][service]['resource_type'][resource_type][resource_status].append(resource_id)
            else:
                sg['used_by'][service]['resource_type'][resource_type].append(resource_id)
    except Exception as e:
        if resource_type in ['elbs', 'functions']:
            pass
        else:
            region = current_path[3]
            vpc_id = current_path[5]
            if vpc_id == ec2_classic:
                pass
            else:
                printError('Failed to parse %s in %s in %s' % (resource_type, vpc_id, region))
                printException(e)
示例#18
0
def match_network_acls_and_subnets_callback(vpc_config, current_config, path, current_path, acl_id, callback_args):
    for association in current_config['Associations']:
        subnet_path = current_path[:-1] + ['subnets', association['SubnetId']]
        subnet = get_object_at(vpc_config, subnet_path)
        subnet['network_acl'] = acl_id
示例#19
0
def process_metadata_callbacks(aws_config):
    """
    Iterates through each type of resource and, when callbacks have been
    configured in the config metadata, recurse through each resource and calls
    each callback.

    :param aws_config:                  The entire AWS configuration object

    :return:                            None
    """
    for service_group in aws_config['metadata']:
        for service in aws_config['metadata'][service_group]:
            if service == 'summaries':
                continue
            # Reset external attack surface
            if 'summaries' in aws_config['metadata'][service_group][service]:
                for summary in aws_config['metadata'][service_group][service][
                        'summaries']:
                    if summary == 'external attack surface' and service in aws_config[
                            'services'] and 'external_attack_surface' in aws_config[
                                'services'][service]:
                        aws_config['services'][service].pop(
                            'external_attack_surface')
            # Reset all global summaries
            if 'service_groups' in aws_config:
                aws_config.pop('service_groups')
            # Resources
            for resource_type in aws_config['metadata'][service_group][
                    service]['resources']:
                if 'callbacks' in aws_config['metadata'][service_group][
                        service]['resources'][resource_type]:
                    current_path = ['services', service]
                    target_path = aws_config['metadata'][service_group][
                        service]['resources'][resource_type]['path'].replace(
                            '.id', '').split('.')[2:]
                    callbacks = aws_config['metadata'][service_group][service][
                        'resources'][resource_type]['callbacks']
                    new_go_to_and_do(aws_config,
                                     get_object_at(aws_config, current_path),
                                     target_path, current_path, callbacks)
            # Summaries
            if 'summaries' in aws_config['metadata'][service_group][service]:
                for summary in aws_config['metadata'][service_group][service][
                        'summaries']:
                    if 'callbacks' in aws_config['metadata'][service_group][
                            service]['summaries'][summary]:
                        current_path = ['services', service]
                        for callback in aws_config['metadata'][service_group][
                                service]['summaries'][summary]['callbacks']:
                            callback_name = callback[0]
                            callback_args = copy.deepcopy(callback[1])
                            target_path = callback_args.pop('path').replace(
                                '.id', '').split('.')[2:]
                            callbacks = [[callback_name, callback_args]]
                            new_go_to_and_do(
                                aws_config,
                                get_object_at(aws_config, current_path),
                                target_path, current_path, callbacks)
    # Group-level summaries
    for service_group in aws_config['metadata']:
        if 'summaries' in aws_config['metadata'][service_group]:
            for summary in aws_config['metadata'][service_group]['summaries']:
                current_path = ['services', service]
                for callback in aws_config['metadata'][service_group][
                        'summaries'][summary]['callbacks']:
                    callback_name = callback[0]
                    callback_args = copy.deepcopy(callback[1])
                    target_path = aws_config['metadata'][service_group][
                        'summaries'][summary]['path'].split('.')
                    target_object = aws_config
                    for p in target_path:
                        manage_dictionary(target_object, p, {})
                        target_object = target_object[p]
                    if callback_name == 'merge':
                        for service in aws_config['metadata'][service_group]:
                            if service == 'summaries':
                                continue
                            if 'summaries' in aws_config['metadata'][
                                    service_group][
                                        service] and summary in aws_config[
                                            'metadata'][service_group][
                                                service]['summaries']:
                                try:
                                    source = get_object_at(
                                        aws_config, aws_config['metadata']
                                        [service_group][service]['summaries']
                                        [summary]['path'].split('.'))
                                except:
                                    source = {}
                                target_object.update(source)