aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Reyna <David.Reyna@windriver.com>2020-01-24 03:14:15 -0800
committerDavid Reyna <David.Reyna@windriver.com>2020-01-24 03:35:10 -0800
commit0895afc7175d7a817dc5d5231cc54d711c0443a1 (patch)
tree0ec24c964e6ec25afd2b4d969710d7cf412121e7
parentb61a07114b6562d5a2c36d5aede937b2b0c88e6e (diff)
downloadsrtool-0895afc7175d7a817dc5d5231cc54d711c0443a1.tar.gz
srtool-0895afc7175d7a817dc5d5231cc54d711c0443a1.tar.bz2
srtool-0895afc7175d7a817dc5d5231cc54d711c0443a1.zip
srtool: fix alt-source updates, improve CVE repair
1. Fix the NIST 'alt-source' routine to correctly use the current 'modified' datasource to preempt the regular datasources, and also set the CVE datasource links accordingly. 2. Update the CVE NIST improve Score/Severity repair, also insure that the 'modified' datasource values pre-empt the regular datasource values. Also, fix missing and/or obsolete NIST datasource references for CVEs. ./bin/common/srtool_utils.py --fix-severity [ALL|"NIST Modified Data"|...] 3. Add/improve helper routine to list Score/Severity values across the many NIST data sources (e.g. modified and regular), plus the the current CVE values and the current CVE datasource links. This is used to investigate and validate the above repair routine. ./bin/nist/srtool_nist.py -S CVE-2020-7470 Signed-off-by: David Reyna <David.Reyna@windriver.com>
-rwxr-xr-xbin/common/srtool_utils.py114
-rwxr-xr-xbin/nist/srtool_nist.py127
-rw-r--r--lib/orm/models.py2
3 files changed, 177 insertions, 66 deletions
diff --git a/bin/common/srtool_utils.py b/bin/common/srtool_utils.py
index 33405c67..573a86d5 100755
--- a/bin/common/srtool_utils.py
+++ b/bin/common/srtool_utils.py
@@ -1084,17 +1084,41 @@ def foo_fix_bad_mitre_init():
# Fix CVE records with missing 'cvssV2_severity' values in the top-level CVE records, due to
# CVE imports before a patch was sent upstream
#
-def fix_v2_severity(datasource_list):
+# The NIST Modified list is processed first. If any of its CVEs are found in a regular
+# list, that CVE is skipped since it was preempted
+#
+
+def fix_severity(datasource_list):
conn = sqlite3.connect(srtDbName)
cur_ds = conn.cursor()
cur_cs = conn.cursor()
cur_cve = conn.cursor()
+ cur_del = conn.cursor()
cve_count = 0
fix_count = 0
+ nist_ds_list = {}
+ modified_cve_list = []
- # Find NIST data sources
- cur_ds.execute('SELECT * FROM orm_datasource WHERE source = "nist" ORDER BY key ASC;')
+ DATA_MAP_V3_Score = 0
+ DATA_MAP_V3_Severity = 1
+ DATA_MAP_V2_Score = 2
+ DATA_MAP_V2_Severity = 3
+
+
+ #
+ # Gather the NIST data source list
+ #
+
+ cur_ds.execute('SELECT * FROM orm_datasource WHERE source = "nist" ORDER BY key DESC;')
+ for i,ds in enumerate(cur_ds):
+ nist_ds_list[ds[ORM.DATASOURCE_ID]] = ds[ORM.DATASOURCE_DESCRIPTION]
+
+ #
+ # Iterate over the NIST data sources
+ #
+
+ cur_ds.execute('SELECT * FROM orm_datasource WHERE source = "nist" ORDER BY key DESC;')
for i,ds in enumerate(cur_ds):
# Development/debug support
if cmd_count and ((cve_count - cmd_skip) > cmd_count):
@@ -1107,6 +1131,7 @@ def fix_v2_severity(datasource_list):
elif not ds[ORM.DATASOURCE_DESCRIPTION] in datasource_list.split(','):
continue
print("NIST Source:%s" % ds[ORM.DATASOURCE_DESCRIPTION])
+ is_modified_list = ds[ORM.DATASOURCE_DESCRIPTION] == 'NIST Modified Data'
# Scan the NIST datasource file and extract required values into a map
# (bin/nist/srtool_nist.py --download-only --source='NIST 2002' --file=data/nvdcve-1.1-2002.json --url-file=nvdcve-1.1-2002.json.gz --url-meta=nvdcve-1.1-2002.meta)
@@ -1118,6 +1143,11 @@ def fix_v2_severity(datasource_list):
break
nist_data_map = {}
nist_file = os.path.join(srtool_basepath,cve_source_file)
+
+ #
+ # Gather the V3/V2 status of all the CVEs in this NIST data sources
+ #
+
try:
f = open(nist_file, 'r')
source_dct = json.load(f)
@@ -1130,9 +1160,17 @@ def fix_v2_severity(datasource_list):
continue
cve_name = item['cve']['CVE_data_meta']['ID']
+ # Is this the NIST Modified list?
+ if is_modified_list:
+ # Add CVE name to Modified list
+ modified_cve_list.append(cve_name)
+ elif cve_name in modified_cve_list:
+ # Skip if already process by Modified list
+ continue
- if cve_name == "CVE-2019-15031":
- print("BAR1:%s" % (item['impact']['baseMetricV3']))
+# # Debugging support
+# if cve_name != "CVE-2016-0887": #"CVE-2020-7470","CVE-2019-15031"
+# continue
cvssV3_baseScore = ''
cvssV3_baseSeverity = ''
@@ -1145,27 +1183,18 @@ def fix_v2_severity(datasource_list):
cvssV2_baseScore = "%.1f" % float(item['impact']['baseMetricV2']['cvssV2']['baseScore'])
cvssV2_severity = item['impact']['baseMetricV2']['severity']
-# print(" Name:%s,cvssV2_severity=%s" % (cve_name,cvssV2_severity))
nist_data_map[cve_name] = [cvssV3_baseScore,cvssV3_baseSeverity,cvssV2_baseScore,cvssV2_severity]
- if cve_name == "CVE-2019-15031":
- print("BAR2:%s" % str(nist_data_map[cve_name]))
-
-
except Exception as e:
print("ERROR:%s (%s)" % (e,item['impact']['baseMetricV3']))
return
+ #
+ # Update the V3/V2 status for all found CVE records in this datasource
+ #
- # Find all CVEs with this datasource
- cur_cs.execute('SELECT * FROM orm_cvesource WHERE datasource_id = %d' % ds[ORM.DATASOURCE_ID])
- for j,cvesource in enumerate(cur_cs):
- # Development/debug support
- cve_count += 1
- if cmd_skip and (cve_count < cmd_skip): continue
- if cmd_count and ((cve_count - cmd_skip) > cmd_count): break
-
- cur_cve.execute('SELECT * FROM orm_cve WHERE id = %d' % cvesource[ORM.CVESOURCE_CVE_ID])
+ for cve_name in nist_data_map:
+ cur_cve.execute('SELECT * FROM orm_cve WHERE name = "%s"' % cve_name)
cve = cur_cve.fetchone()
if not cve:
print("WARNING: MISSING CVE in orm_cvesource '%d:%d' : %s" % (cvesource[ORM.CVESOURCE_CVE_ID],cvesource[ORM.CVESOURCE_DATASOURCE_ID],ds[ORM.DATASOURCE_DESCRIPTION]))
@@ -1173,18 +1202,53 @@ def fix_v2_severity(datasource_list):
cve_name = cve[ORM.CVE_NAME]
if cve_name in nist_data_map:
fix_count += 1
- if (nist_data_map[cve_name][0] != cve[ORM.CVE_CVSSV3_BASESCORE]) or (nist_data_map[cve_name][1] != cve[ORM.CVE_CVSSV3_BASESEVERITY]):
- print("WARNING: diff V3 for %s (%s->%s) (%s->%s)" % (cve_name,nist_data_map[cve_name][0],cve[ORM.CVE_CVSSV3_BASESCORE],nist_data_map[cve_name][1],cve[ORM.CVE_CVSSV3_BASESEVERITY]))
+ if (nist_data_map[cve_name][DATA_MAP_V3_Score] != cve[ORM.CVE_CVSSV3_BASESCORE]) or (nist_data_map[cve_name][DATA_MAP_V3_Severity] != cve[ORM.CVE_CVSSV3_BASESEVERITY]) or \
+ (nist_data_map[cve_name][DATA_MAP_V2_Score] != cve[ORM.CVE_CVSSV2_BASESCORE]) or (nist_data_map[cve_name][DATA_MAP_V2_Severity] != cve[ORM.CVE_CVSSV2_SEVERITY ]):
+ print("CHANGE: %s V3(%s to %s,%s to %s)V2(%s to %s,%s to %s)" % (cve_name,cve[ORM.CVE_CVSSV3_BASESCORE],nist_data_map[cve_name][DATA_MAP_V3_Score],cve[ORM.CVE_CVSSV3_BASESEVERITY],nist_data_map[cve_name][DATA_MAP_V3_Severity],
+ cve[ORM.CVE_CVSSV2_BASESCORE],nist_data_map[cve_name][DATA_MAP_V2_Score],cve[ORM.CVE_CVSSV2_SEVERITY ],nist_data_map[cve_name][DATA_MAP_V2_Severity]))
if force:
sql = ''' UPDATE orm_cve
SET cvssV3_baseScore = ?, cvssV3_baseSeverity = ?, cvssV2_baseScore = ?, cvssV2_severity = ?
WHERE id = ?'''
- cur_cve.execute(sql, (nist_data_map[cve_name][0],nist_data_map[cve_name][1],nist_data_map[cve_name][2],nist_data_map[cve_name][3],cve[ORM.CVE_ID],))
+ cur_cve.execute(sql, (nist_data_map[cve_name][DATA_MAP_V3_Score],nist_data_map[cve_name][DATA_MAP_V3_Severity],nist_data_map[cve_name][DATA_MAP_V2_Score],nist_data_map[cve_name][DATA_MAP_V2_Severity],cve[ORM.CVE_ID],))
# print('%05d: %-20s = %-20s' % (j,cve_name,nist_data_map[cve_name]))
else:
print("ERROR:CVE_NAME '%s' NOT MAPPED" % cve_name)
+ #
+ # Repair the data source mappings
+ # * Add missing NIST links
+ # * Replace old NIST links with found links (e.g. Modified datasource preempts regular datasources)
+ #
+
+ found_mapping = False
+ cur_cs.execute('SELECT * FROM orm_cvesource WHERE cve_id = %d' % cve[ORM.CVE_ID])
+ for j,cve2ds in enumerate(cur_cs):
+ if cve2ds[ORM.CVESOURCE_DATASOURCE_ID] in nist_ds_list:
+ # Do we have an obsolete NIST mapping?
+ if cve2ds[ORM.CVESOURCE_DATASOURCE_ID] != ds[ORM.DATASOURCE_ID]:
+ # Delete old mapping
+ print("Delete old mapping %s,%s" % (cve_name,nist_ds_list[cve2ds[ORM.CVESOURCE_DATASOURCE_ID]]))
+ if force:
+ sql = 'DELETE FROM orm_cvesource WHERE id=?'
+ cur_del.execute(sql, (cve2ds[ORM.CVESOURCE_ID],))
+ else:
+ # We are good to go
+ found_mapping = True
+ # Add if missing or deleted as obsolete
+ if not found_mapping:
+ print("Insert new mapping %s,%s" % (cve_name,nist_ds_list[ds[ORM.DATASOURCE_ID]]))
+ if force:
+ sql = ''' INSERT into orm_cvesource (cve_id, datasource_id) VALUES (?, ?)'''
+ cur_cs.execute(sql, (cve[ORM.CVE_ID],ds[ORM.DATASOURCE_ID],))
+
+
+ # Development/debug support
+ cve_count += 1
+ if cmd_skip and (cve_count < cmd_skip): continue
+ if cmd_count and ((cve_count - cmd_skip) > cmd_count): break
+
# Progress indicator support
if (0 == cve_count % 1000):
print('%05d: %-20s\r' % (cve_count,cve_name), end='')
@@ -1497,8 +1561,8 @@ def main(argv):
parser.add_argument('--fix-remove-bulk-cve-history', action='store_const', const='fix_remove_bulk_cve_history', dest='command', help='foo')
parser.add_argument('--fix-bad-mitre-init', action='store_const', const='fix_bad_mitre_init', dest='command', help='foo')
parser.add_argument('--fix-bad-new', action='store_const', const='fix_bad_new', dest='command', help='foo')
- parser.add_argument('--fix-v2-severity', dest='fix_v2_severity', help='foo')
+ parser.add_argument('--fix-severity', dest='fix_severity', help='Fix bad score/severity values, broken cve source links')
parser.add_argument('--find-empty-status', action='store_const', const='find_empty_status', dest='command', help='foo')
parser.add_argument('--find-multiple-defects', action='store_const', const='find_multiple_defects', dest='command', help='foo')
@@ -1573,8 +1637,8 @@ def main(argv):
fix_bad_mitre_init()
elif 'fix_bad_new' == args.command:
fix_bad_new()
- elif args.fix_v2_severity:
- fix_v2_severity(args.fix_v2_severity)
+ elif args.fix_severity:
+ fix_severity(args.fix_severity)
elif 'find_multiple_defects' == args.command:
find_multiple_defects()
diff --git a/bin/nist/srtool_nist.py b/bin/nist/srtool_nist.py
index e93f0882..021836b9 100755
--- a/bin/nist/srtool_nist.py
+++ b/bin/nist/srtool_nist.py
@@ -113,6 +113,14 @@ def get_name_sort(cve_name):
cve_name_sort = cve_name
return cve_name_sort
+# Extract the source file path from the "Lookup" command
+def get_file_from_lookup(lookup):
+ for param in lookup.split(' '):
+ if param.startswith('--file='):
+ return(param.replace('--file=',''))
+ return('')
+
+
#######################################################################
# CVE_ItemToSummary: Translate a CVE_Item JSON node to a dictionary
@@ -760,6 +768,7 @@ def file_date(filename,utc=False):
#
def do_fetch_cve(cve_name,cve_source_file,use_cache=True):
+
# Fetch cached data, else extract data from datasource file
cache_path = os.path.join(srtool_basepath, nist_cache_dir)
cve_cache_path = os.path.join(cache_path, cve_name + ".json")
@@ -804,11 +813,11 @@ def do_fetch_cve(cve_name,cve_source_file,use_cache=True):
return None
if not CVE_Item:
- print("description=There is no CVE record for %s in the loaded NIST public CVE database." % cve_name)
+ # Not found
return None
-
- # Translate a CVE_Item JSON node
- return(CVE_ItemToSummary(CVE_Item))
+ else:
+ # Return translated CVE_Item JSON node
+ return(CVE_ItemToSummary(CVE_Item))
def fetch_cve(cve_name,cve_source_file):
summary = do_fetch_cve(cve_name,cve_source_file)
@@ -832,30 +841,26 @@ def cve_summary(cve_name):
base_id = []
modified_id = []
- def get_file(lookup):
- for param in lookup.split(' '):
- if param.startswith('--file='):
- return(param.replace('--file=',''))
- return('')
-
- def show_summary(cve_name,datasource_map):
- summary = do_fetch_cve(cve_name,datasource_map[DSMAP_FILE],False)
- if summary:
+ def description_summary(description):
desc_sum = 0
- description = summary['description']
for ch in description:
desc_sum += ord(ch)
if 37 < len(description):
description = "%-37s..." % description[:37]
- print(" * Name:%s in %s (%s,%s)" % (summary['name'],datasource_map[DSMAP_FILE],datasource_map[DSMAP_MOD],datasource_map[DSMAP_UPDATE]))
- print(" description :%-40s [sum=%d]" % (description,desc_sum))
+ return("%-40s [sum=%d]" % (description,desc_sum))
+
+ def show_summary(key,cve_name,datasource_map):
+ summary = do_fetch_cve(cve_name,datasource_map[DSMAP_FILE],False)
+ if summary:
+ print(" %s: %s in %s (%s,%s)" % (key,summary['name'],datasource_map[DSMAP_FILE],datasource_map[DSMAP_MOD],datasource_map[DSMAP_UPDATE]))
+ print(" description :%s" % description_summary(summary['description']))
print(" cvssV3_baseScore :%s" % summary['cvssV3_baseScore'])
print(" cvssV3_baseSeverity:%s" % summary['cvssV3_baseSeverity'])
print(" cvssV2_baseScore :%s" % summary['cvssV2_baseScore'])
print(" cvssV2_severity :%s" % summary['cvssV2_severity'])
print(" lastModifiedDate :%s" % summary['lastModifiedDate'])
else:
- print(" There is no CVE record for %s in %s" % (cve_name,base_file))
+ print(" %s: There is no CVE record for %s in %s" % (key,cve_name,datasource_map[DSMAP_FILE]))
cur_ds.execute('SELECT * FROM orm_datasource;')
datasource_map = {}
@@ -865,28 +870,39 @@ def cve_summary(cve_name):
# DataSource Map is [cve_file,ds_desc,ds_lastmodifieddate,ds_lastupdateddate]
datasource_map[datasource[ORM.DATASOURCE_ID]] = ['',datasource[ORM.DATASOURCE_DESCRIPTION],datasource[ORM.DATASOURCE_LASTMODIFIEDDATE],datasource[ORM.DATASOURCE_LASTUPDATEDDATE]]
if ('nist' == datasource[ORM.DATASOURCE_SOURCE]) and ('NIST Modified Data' == datasource[ORM.DATASOURCE_DESCRIPTION]):
- datasource_map[datasource[ORM.DATASOURCE_ID]][DSMAP_FILE] = get_file(datasource[ORM.DATASOURCE_LOOKUP])
+ datasource_map[datasource[ORM.DATASOURCE_ID]][DSMAP_FILE] = get_file_from_lookup(datasource[ORM.DATASOURCE_LOOKUP])
modified_id = datasource[ORM.DATASOURCE_ID]
elif ('nist' == datasource[ORM.DATASOURCE_SOURCE]) and datasource[ORM.DATASOURCE_CVE_FILTER] and cve_name.startswith(datasource[ORM.DATASOURCE_CVE_FILTER]):
- datasource_map[datasource[ORM.DATASOURCE_ID]][DSMAP_FILE] = get_file(datasource[ORM.DATASOURCE_LOOKUP])
+ datasource_map[datasource[ORM.DATASOURCE_ID]][DSMAP_FILE] = get_file_from_lookup(datasource[ORM.DATASOURCE_LOOKUP])
base_id = datasource[ORM.DATASOURCE_ID]
- #print("FOO2:%s,%s" % (base_id,modified_id))
# Return the NIST results
print("NIST Summary:")
- show_summary(cve_name,datasource_map[base_id])
- show_summary(cve_name,datasource_map[modified_id])
- # Return the DataSource mapping results
- print("DataSource Summary:")
- cur_cve.execute('SELECT * FROM orm_cve WHERE name = "%s"' % cve_name)
- for i,cve in enumerate(cur_cve):
+ show_summary("BASE",cve_name,datasource_map[base_id])
+ show_summary("MOD ",cve_name,datasource_map[modified_id])
+ cve = cur_cve.execute('SELECT * FROM orm_cve WHERE name = "%s"' % cve_name).fetchone()
+ if cve:
cur_ds.execute('SELECT * FROM orm_cvesource WHERE cve_id = %d' % cve[ORM.CVE_ID])
+ # Return the CVE record's current values
+ print("CVE Summary:")
+ print(" CVE : %s" % (cve[ORM.CVE_NAME]))
+ print(" description :%s" % description_summary(cve[ORM.CVE_DESCRIPTION]))
+ print(" cvssV3_baseScore :%s" % cve[ORM.CVE_CVSSV3_BASESCORE])
+ print(" cvssV3_baseSeverity:%s" % cve[ORM.CVE_CVSSV3_BASESEVERITY])
+ print(" cvssV2_baseScore :%s" % cve[ORM.CVE_CVSSV2_BASESCORE])
+ print(" cvssV2_severity :%s" % cve[ORM.CVE_CVSSV2_SEVERITY])
+ print(" lastModifiedDate :%s" % cve[ORM.CVE_LASTMODIFIEDDATE])
+ # Return the DataSource mapping results
+ print("DataSource Summary:")
for j,cs in enumerate(cur_ds):
datasource_id = cs[ORM.CVESOURCE_DATASOURCE_ID]
if datasource_id in datasource_map:
print(" [%2d] %s" % (j+1,datasource_map[cs[ORM.CVESOURCE_DATASOURCE_ID]][DSMAP_DESC]))
else:
print(" [%2d] Unknown DataSource ID %d" % (j+1,cs[ORM.CVESOURCE_DATASOURCE_ID]))
+ else:
+ print("CVE Summary:")
+ print(" CVE : There is no CVE record for %s in orm_cve" % (cve_name))
#######################################################################
@@ -898,7 +914,14 @@ def cve_summary(cve_name):
# as data sources that are on-demand only
#
-def update_cve_list(action,cve_list,conn=None):
+def update_cve_list(action,cve_string_list,conn=None):
+ cve_list = cve_string_list.split(',')
+
+ DS_MODIFIED_SOURCE = 0
+ DS_CVEFILTER = 1
+ DS_LOOKUP = 2
+ DS_ID = 3
+ DS_SOURCE_FILE = 4
# Set up database connection
do_close = False
@@ -911,11 +934,20 @@ def update_cve_list(action,cve_list,conn=None):
sql = "SELECT * FROM orm_datasource"
cur.execute(sql)
datasource_table = []
+ datasource_nist_ids = {}
for datasource in cur:
if 'nist' != datasource[ORM.DATASOURCE_SOURCE]:
# Only consider NIST datasources
continue
- datasource_table.append([datasource[ORM.DATASOURCE_CVE_FILTER], datasource[ORM.DATASOURCE_LOOKUP], datasource[ORM.DATASOURCE_ID]])
+
+ # Track the IDs for NIST sources
+ datasource_nist_ids[datasource[ORM.DATASOURCE_ID]] = True
+
+ # Always put the Modified source first
+ if 'NIST Modified Data' == datasource[ORM.DATASOURCE_DESCRIPTION]:
+ datasource_table.insert(0,[True,datasource[ORM.DATASOURCE_CVE_FILTER], datasource[ORM.DATASOURCE_LOOKUP], datasource[ORM.DATASOURCE_ID], get_file_from_lookup(datasource[ORM.DATASOURCE_LOOKUP]) ])
+ else:
+ datasource_table.append([False,datasource[ORM.DATASOURCE_CVE_FILTER], datasource[ORM.DATASOURCE_LOOKUP], datasource[ORM.DATASOURCE_ID], get_file_from_lookup(datasource[ORM.DATASOURCE_LOOKUP]) ])
update = False
fd = None
@@ -928,17 +960,17 @@ def update_cve_list(action,cve_list,conn=None):
fd = None
source_dct = []
has_matches = False
- # Find at least one CVE that is in this datasource
- for cve_name in cve_list.split(','):
- if (not datasource[0]) or cve_name.startswith(datasource[0]):
+ # Find at least one CVE that is in this datasource, and always scan the Modified source
+ for cve_name in cve_list:
+ if datasource[DS_MODIFIED_SOURCE] or cve_name.startswith(datasource[DS_CVEFILTER]):
has_matches = True
+ break
if not has_matches:
continue
# Find the CVEs in this datasource
# bin/nist/srtool_nist.py --file=data/nvdcve-1.0-2002.json %command%
- cve_source_file = re.sub(r".*=", "", datasource[1])
- cve_source_file = re.sub(r" .*", "", cve_source_file)
+ cve_source_file = datasource[DS_SOURCE_FILE]
if verbose: print("NIST_SOURCE:%s %s" % (cve_source_file,cve_name))
try:
if not fd:
@@ -952,10 +984,18 @@ def update_cve_list(action,cve_list,conn=None):
continue
if not 'ID' in item['cve']['CVE_data_meta']:
continue
- for cve_name in cve_list.split(','):
+
+ # Use a temp CVE list so that Modified" can safely remove found CVEs from the main CVE list
+ cve_list_local = cve_list
+ for cve_name in cve_list_local:
if item['cve']['CVE_data_meta']['ID'] == cve_name:
if verbose: print(" NIST_TRANSLATE:%s %s" % (cve_source_file,cve_name))
+ # If found in the Modified List, remove it from further consideration by regular sources
+ if datasource[DS_MODIFIED_SOURCE]:
+ cve_list.remove(cve_name)
+ if verbose: print(" NIST_FOUND_MODIFIED_REMOVE_NAME:%s" % cve_name)
+
# Translate the CVE content
summary = CVE_ItemToSummary(item,True)
# Commit the CVE content
@@ -963,13 +1003,18 @@ def update_cve_list(action,cve_list,conn=None):
if is_change:
update = True
- # Add NIST datasource to CVE
- sql = '''SELECT * FROM orm_cvesource WHERE cve_id=? AND datasource_id=?'''
- cve2ds = cur.execute(sql, (cve_id, datasource[2],)).fetchone()
- if not cve2ds:
- sql = ''' INSERT into orm_cvesource (cve_id, datasource_id) VALUES (?, ?)'''
- cur.execute(sql, (cve_id,datasource[2],))
- # Remember this match in case it gets preempted
+ # First, remove all existing (potentially obsolete) NIST datasources to CVE
+ sql = '''SELECT * FROM orm_cvesource WHERE cve_id=?'''
+ for cve2ds in cur.execute(sql, (cve_id, )):
+ if cve2ds[ORM.CVESOURCE_DATASOURCE_ID] in datasource_nist_ids:
+ sql = 'DELETE FROM orm_cvesource WHERE id=?'
+ cur.execute(sql, (cve2ds[ORM.CVESOURCE_ID],))
+ if verbose: print(" NIST_REMOVE_OLDSOURCE:%s" % (cve2ds[ORM.CVESOURCE_DATASOURCE_ID]))
+ # Second, add found NIST datasource to CVE
+ sql = ''' INSERT into orm_cvesource (cve_id, datasource_id) VALUES (?, ?)'''
+ cur.execute(sql, (cve_id,datasource[DS_ID],))
+ # Note, CVE top record was updated with found values (NIST wins over other sources)
+ # when sql_cve_query() executed
if verbose: print(" NIST_QUERIED:%s %s" % (cve_source_file,cve_name))
diff --git a/lib/orm/models.py b/lib/orm/models.py
index 0dd73ba4..47d59415 100644
--- a/lib/orm/models.py
+++ b/lib/orm/models.py
@@ -406,6 +406,8 @@ class HelpText(models.Model):
#UPDATE_FREQUENCY: 0 = every minute, 1 = every hour, 2 = every day, 3 = every week, 4 = every month, 5 = every year
class DataSource(models.Model):
+ search_allowed_fields = ['key', 'name', 'description', 'init', 'update', 'lookup']
+
#UPDATE FREQUENCT
MINUTELY = 0
HOURLY = 1