Пример #1
0
async def db_import_cve(cve: str, conn: Connection):
    """Import missing CVE metadata into database"""
    # Attempt to get CVE data from VMAAS
    LOGGER.info("Attempting to get %s data from VMAAS", cve)
    cve_request_endpoint = format_vmaas_cve_endpoint(cve)

    cve_page = await vmaas_request(cve_request_endpoint, method="GET")
    success = True

    try:
        cve_data = cve_page["cve_list"][cve]
    except (KeyError, TypeError):
        LOGGER.error("Error importing %s from VMAAS", cve)
        success = False
    try:
        async with conn.transaction():
            if success:
                impact_id_map = {}
                async for row in conn.cursor(
                        "SELECT name, id FROM cve_impact"):
                    impact_name, impact_id = row
                    impact_id_map[impact_name] = impact_id

                cve_row = construct_cve_row(cve_data,
                                            impact_id_map,
                                            asyncpg_type=True)
                inserted = await conn.fetchrow(
                    """INSERT INTO cve_metadata
                                       (cve, description, impact_id, public_date, modified_date,
                                       cvss3_score, cvss3_metrics, cvss2_score, cvss2_metrics, redhat_url,
                                       secondary_url, advisories_list)
                                       VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
                                       ON CONFLICT (cve) DO UPDATE
                                       SET
                                         description = EXCLUDED.description,
                                         impact_id = EXCLUDED.impact_id,
                                         public_date = EXCLUDED.public_date,
                                         modified_date = EXCLUDED.modified_date,
                                         cvss3_score = EXCLUDED.cvss3_score,
                                         cvss3_metrics = EXCLUDED.cvss3_metrics,
                                         cvss2_score = EXCLUDED.cvss2_score,
                                         cvss2_metrics = EXCLUDED.cvss2_metrics,
                                         redhat_url = EXCLUDED.redhat_url,
                                         secondary_url = EXCLUDED.secondary_url,
                                         advisories_list = EXCLUDED.advisories_list
                                       RETURNING id AS inserted""", *cve_row)

            # if vmaas was not available insert empty cve
            else:
                inserted = await conn.fetchrow(
                    """INSERT INTO cve_metadata (cve, description, impact_id)
                                                    VALUES ($1, $2, $3)
                                                    ON CONFLICT (cve) DO UPDATE
                                                    SET cve = $1
                                                    RETURNING id AS inserted""",
                    cve, 'unknown', 0)
            CVES_CACHE[cve] = inserted[0]
    # pylint: disable=broad-except
    except Exception:
        DATABASE_ERROR.inc()
        LOGGER.exception("Error during inserting CVE: ")
Пример #2
0
async def db_import_rule_hits(conn: Connection, rh_account_id: int,
                              inventory_id: str, system_id: int,
                              rule_hits: dict) -> None:
    """Associate rules hits with system"""
    # pylint: disable=too-many-branches, too-many-statements

    active_rules = set()
    rules_playbook_count = {}
    async for row in conn.cursor(
            """SELECT ir.id, ir.playbook_count, ir.active FROM insights_rule ir"""
    ):
        rule_id, rule_playbook_count, rule_active = row
        rules_playbook_count[rule_id] = rule_playbook_count
        if rule_active:
            active_rules.add(rule_id)

    to_update = []
    rule_hits_cves_ids = tuple(rule_hits.keys())
    system_cves = []

    async for row in conn.cursor(
            """SELECT sv.id, sv.cve_id, sv.rule_id, sv.when_mitigated, sv.advisory_available, cm.cve
                                    FROM system_vulnerabilities sv
                                    JOIN cve_metadata cm ON sv.cve_id = cm.id
                                    WHERE system_id = $1 AND rh_account_id = $2""",
            system_id, rh_account_id):
        row_id, cve_id, rule_id, when_mitigated, advisory_available, cve = row
        playbook_count = rules_playbook_count.get(
            rule_hits.get(cve_id, {}).get('id'))
        mitigation_reason = rule_hits.get(cve_id, {}).get('mitigation_reason')
        remediation_type_id = get_available_remediation_type(
            advisory_available, when_mitigated, mitigation_reason,
            playbook_count)
        if cve_id in rule_hits_cves_ids:
            if 'mitigation_reason' in rule_hits[cve_id]:
                if rule_hits[cve_id][
                        'id'] not in active_rules and not when_mitigated:
                    system_cves.append(cve)
                to_update.append(
                    (row_id, rh_account_id, rule_hits[cve_id]['id'], None,
                     rule_hits[cve_id]['mitigation_reason'],
                     advisory_available, remediation_type_id))
            else:
                to_update.append(
                    (row_id, rh_account_id, rule_hits[cve_id]['id'],
                     rule_hits[cve_id]['details'], None, advisory_available,
                     remediation_type_id))
                if rule_hits[cve_id][
                        'id'] in active_rules or not when_mitigated:
                    system_cves.append(cve)
            del rule_hits[
                cve_id]  # rule hits become dict of completely new system cves
        elif rule_id:
            to_update.append((row_id, rh_account_id, None, None, None,
                              advisory_available, remediation_type_id))
            if not when_mitigated:
                system_cves.append(cve)
        elif not when_mitigated:
            system_cves.append(cve)

    if rule_hits:
        await insert_new_cves(conn, rh_account_id, system_id, rule_hits,
                              rules_playbook_count)
        system_cves.extend([
            rule_hits[cve]['cve_name'] for cve in rule_hits
            if rule_hits[cve]['id'] in active_rules
            and 'details' in rule_hits[cve]
        ])
    if to_update:
        await update_cves(conn, to_update, rh_account_id)

    await _update_system(system_id, len(system_cves), conn)

    send_remediations_update(REMEDIATIONS_PRODUCER, inventory_id, system_cves)