aboutsummaryrefslogtreecommitdiffstats
path: root/bin/srtool_cve.py
diff options
context:
space:
mode:
Diffstat (limited to 'bin/srtool_cve.py')
-rwxr-xr-xbin/srtool_cve.py608
1 files changed, 608 insertions, 0 deletions
diff --git a/bin/srtool_cve.py b/bin/srtool_cve.py
new file mode 100755
index 00000000..343b8138
--- /dev/null
+++ b/bin/srtool_cve.py
@@ -0,0 +1,608 @@
+#!/usr/bin/env python3
+#
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+#
+# Security Response Tool Commandline Tool
+#
+# Copyright (C) 2018 Wind River Systems
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+### Usage Examples (run from top level directory)
+# Updating a specific NIST feed: ./bin/srtool.py -u "NIST JSON Data 2017"
+# Updating with the NIST incremental feed: ./bin/srtool.py -U
+
+import os
+import sys
+import re
+import csv
+import xml.etree.ElementTree as ET
+import argparse
+import sqlite3
+import subprocess
+import json
+import urllib
+
+try:
+ from datetime import datetime, date
+ from urllib.request import urlopen, URLError
+ from urllib.parse import urlparse
+except ImportError:
+ from urllib2 import urlopen, URLError
+ from urlparse import urlparse
+
+# setup
+lookupTable = []
+cveIndex = {}
+db_change = False
+
+srtDbName = 'srt.sqlite'
+is_verbose = False
+
+keywords_for = []
+keywords_against = []
+
+#################################
+# Helper methods
+#
+
+overrides = {}
+
+def set_override(key,value=None):
+ if not value is None:
+ overrides[key] = value
+ elif key in os.environ.keys():
+ overrides[key] = 'yes' if os.environ[key].startswith('1') else 'no'
+ else:
+ overrides[key] = ''
+ print("OVERRIDE: %s = %s" % (key,overrides[key]))
+
+def get_override(key):
+ if key in overrides.keys():
+ return overrides[key]
+ return ''
+
+
+#################################
+# check for updates and apply if any
+#
+# Change orm_datasource schema to make LastModifiedDate a datetime object
+# datetime and urllib imports may be in an inappropriate location (top of file currently)
+
+#gets CVE-Modified feed, determines if we are out of date, and applies updates if true
+#tracks history in update_log.txt
+#incremental argument is boolean that idicates if bulk updating or incremental updating.
+def update_nist(datasource_description, incremental):
+ DS_ID = 0
+ DS_DATA = 1
+ DS_SOURCE = 2
+ DS_TYPE = 3
+ DS_DESCRIPTION = 4
+ DS_FILE_PATH = 5
+ DS_URL = 6
+ DS_LOADED = 7
+ DS_META_URL = 8
+ DS_LAST_MODIFIED_DATE = 9
+
+ #update log (1=Monday, 7= Sunday)
+ today = datetime.today()
+ weeknum = today.strftime("%W")
+ weekday = today.isoweekday()
+ log = open(os.path.join(SRT_BASE_DIR,"update_logs/update_nist_log_%s_%s.txt" % (weeknum, weekday)), "a")
+
+
+ #ensure cache folder exists (clear cache during "run_all_updates()" from "srtool_utils.py")
+ path = os.path.join(SRT_BASE_DIR, "data/cache")
+ try:
+ os.makedirs(path)
+ except:
+ pass
+
+ # Set up database connection
+ conn = sqlite3.connect(srtDbName)
+ c = conn.cursor()
+
+ # Fetch the keywords used to generate recommendation scores
+ global keywords_for
+ global keywords_against
+ sql = "SELECT * FROM orm_srtsetting WHERE name=?"
+ keywords_for = c.execute(sql, ("keywords_for",)).fetchone()[3].split("|")
+ keywords_against = c.execute(sql, ("keywords_against",)).fetchone()[3].split("|")
+
+ sql = "SELECT * FROM orm_datasource WHERE description='%s'" % datasource_description
+ c.execute(sql)
+ for ds in c:
+ try:
+ f = urlopen(ds[DS_META_URL]) #Note: meta files are not in json format, hence manual parse
+ content = f.readline().decode('UTF-8')
+ date_new = datetime.strptime(content, 'lastModifiedDate:%Y-%m-%dT%H:%M:%S-04:00\r\n')
+ date_past = datetime.strptime(ds[DS_LAST_MODIFIED_DATE], '%Y-%m-%d %H:%M:%S')
+
+ log.write("BEGINNING NIST UPDATES\n")
+ #determine if we are out of date and apply updates if true
+ if (date_new > date_past):
+ pre_update_time = datetime.now() #used for logging purposes only
+
+ nist_json(ds[DS_FILE_PATH], ds[DS_URL], ds[DS_ID], ds[DS_FILE_PATH], log, date_past, incremental)
+ log.write("began updates: %s\n" % str(pre_update_time))
+ log.write("finished updates: %s\n" % str(datetime.now()) )
+ log.write("=============================================================================\n")
+ log.write("\n")
+
+ #update datasource's lastModifiedDate after successsfuly updating it
+ sql = "UPDATE orm_datasource SET lastModifiedDate = ? WHERE id='%s'" % ds[DS_ID]
+ #c.execute(sql, (str(date_new),))
+ conn.commit()
+ else:
+
+ log.write("No update needed\n")
+ log.write("Checked: %s\n" % datetime.now())
+ log.write("=============================================================================\n")
+ log.write("\n")
+ print("NO UPDATE NEEDED")
+
+ # Reset datasource's update_time as today
+ sql = "UPDATE orm_datasource SET update_time = ? WHERE id='%s'" % ds[DS_ID]
+ c.execute(sql, (datetime.today().strftime('%Y-%m-%d %H:%M:%S'),) )
+ conn.commit()
+
+ #######
+ ## TESTING PURPOSES ONLY: reset lastModifiedDate so will always need update!
+ #######
+ # sql = '''UPDATE orm_datasource
+ # SET lastModifiedDate = "0001-01-01 01:01:01"
+ # WHERE description="NIST JSON Modified Data 2017" '''
+ # c.execute(sql)
+ # conn.commit()
+
+ f.close()
+ except URLError as e:
+ raise Exception("Failed to open %s: %s" % (href, e.reason))
+ continue
+ log.close()
+ c.close()
+ conn.close()
+
+def nist_scan_configuration_or(cve, cpe_or_node, name, and_enum):
+ cpe_list = '[or]|'
+ for cpe in cpe_or_node['cpe']:
+ cpe23Uri = cpe['cpe23Uri']
+ if 'cpeMatchString' in cpe:
+ cpeMatchString = cpe['cpeMatchString']
+ else:
+ cpeMatchString = ''
+ if 'versionEndIncluding' in cpe:
+ versionEndIncluding = cpe['versionEndIncluding']
+ else:
+ versionEndIncluding = ''
+ cpe_list += '%s,%s,%s,%s|' % (cpe['vulnerable'],cpe23Uri,cpeMatchString,versionEndIncluding)
+ cpe_list += '[/or]|'
+ return cpe_list
+
+#parses JSON, creates CVE object, and updates database as necessary. Commits to database on success
+#will EITHER create new record in orm_cve if cve does not exist OR overwrite every field if existing cve out-of-date OR ignore cve
+#requires json to be formatted with NIST Json schema (https://csrc.nist.gov/schema/nvd/feed/0.1/nvd_cve_feed_json_0.1_beta.schema)
+def nist_json(file_path, json_url, datasource_id, datasource_filename, log, date_past, incremental):
+ import traceback
+ import gzip
+ import requests
+
+ response = urlopen(json_url)
+ dct = json.loads(gzip.decompress(response.read()).decode('utf-8')) #uncompress and decode json.gz
+
+ #save datasource feed to "data"
+ datasource_file = open(os.path.join(SRT_BASE_DIR, datasource_filename), 'w+')
+ datasource_file.write(json.dumps(dct))
+
+ conn = sqlite3.connect(srtDbName)
+ c = conn.cursor()
+
+ CVE_Items = dct['CVE_Items']
+ total = len(CVE_Items)
+ v = Cve()
+
+ cache_path = os.path.join(SRT_BASE_DIR, "data/cache")
+ #begin parsing each cve in the JSON data
+ for i, CVE_Item in enumerate(CVE_Items):
+ # Development support
+ if get_override('SRTDBG_MINIMAL_DB') and (i > 10):
+ break
+
+ cve = CVE_Item['cve']
+ references = cve['references']['reference_data']
+ CVE_data_meta = cve['CVE_data_meta']['ID']
+
+ #if cve exists in cache, delete it
+ cve_path = os.path.join(cache_path, CVE_data_meta + ".json")
+ if (os.path.isfile(cve_path)):
+ os.remove(cve_path)
+
+ #if incremental update, save json copy of the cve to cache
+ if incremental:
+ file = open(cve_path, 'w+')
+ file.write(json.dumps(CVE_Item))
+
+ #print('.', end='', flush=True)
+ print('[%4d]%30s\r' % ((i * 100)/ total, CVE_data_meta), end='', flush=True)
+ try:
+ v.name = CVE_data_meta
+ v.source = 'NIST'
+ v.datasource = datasource_id
+
+ v.cve_data_type = cve['data_type']
+ v.cve_data_format = cve['data_format']
+ v.cve_data_version = cve['data_version']
+
+ v.description = cve['description']['description_data'][0]['value']
+ v.publishedDate = re.sub('T.*','',CVE_Item['publishedDate'])
+ v.lastModifiedDate = re.sub('T.*','',CVE_Item['lastModifiedDate'])
+ v.public = True #always true since NIST is public source
+ v.publish = Cve.PUBLISH_PUBLISHED
+ v.publish_date = v.publishedDate
+
+ if ('impact' in CVE_Item) and ('baseMetricV3' in CVE_Item['impact']):
+ baseMetricV3 = CVE_Item['impact']['baseMetricV3']
+ v.cvssV3_baseScore = baseMetricV3['cvssV3']['baseScore']
+ v.cvssV3_baseSeverity = baseMetricV3['cvssV3']['baseSeverity']
+ # v.cvssV3_vectorString = baseMetricV3['cvssV3']['vectorString']
+ # v.cvssV3_exploitabilityScore = baseMetricV3['exploitabilityScore']
+ # v.cvssV3_impactScore = baseMetricV3['impactScore']
+ # v.cvssV3_attackVector = baseMetricV3['cvssV3']['attackVector']
+ # v.cvssV3_attackComplexity = baseMetricV3['cvssV3']['attackComplexity']
+ # v.cvssV3_privilegesRequired = baseMetricV3['cvssV3']['privilegesRequired']
+ # v.cvssV3_userInteraction = baseMetricV3['cvssV3']['userInteraction']
+ # v.cvssV3_scope = baseMetricV3['cvssV3']['scope']
+ # v.cvssV3_confidentialityImpact = baseMetricV3['cvssV3']['confidentialityImpact']
+ # v.cvssV3_integrityImpact = baseMetricV3['cvssV3']['integrityImpact']
+ # v.cvssV3_availabilityImpact = baseMetricV3['cvssV3']['availabilityImpact']
+ if ('impact' in CVE_Item) and ('baseMetricV2' in CVE_Item['impact']):
+ baseMetricV2 = CVE_Item['impact']['baseMetricV2']
+ v.cvssV2_baseScore = baseMetricV2['cvssV2']['baseScore']
+ # v.cvssV2_severity = baseMetricV2['severity']
+ # v.cvssV2_vectorString = baseMetricV2['cvssV2']['vectorString']
+ # v.cvssV2_exploitabilityScore = baseMetricV2['exploitabilityScore']
+ # v.cvssV2_impactScore = baseMetricV2['exploitabilityScore']
+ # v.cvssV2_accessVector = baseMetricV2['cvssV2']['accessVector']
+ # v.cvssV2_accessComplexity = baseMetricV2['cvssV2']['accessComplexity']
+ # v.cvssV2_authentication = baseMetricV2['cvssV2']['authentication']
+ # v.cvssV2_confidentialityImpact = baseMetricV2['cvssV2']['confidentialityImpact']
+ # v.cvssV2_integrityImpact = baseMetricV2['cvssV2']['integrityImpact']
+
+ # configurations = CVE_Item['configurations']
+ # is_first_and = True
+ # for i, config in enumerate(configurations['nodes']):
+ # v.cpe_list += '[config]|'
+ # v.cpe_list += '[and]|'
+ # if "AND" == config['operator']:
+ # # create AND record
+ # if not is_first_and:
+ # v.cpe_list += '[/and]|'
+ # v.cpe_list += '[and]|'
+ # #is_first_and = False
+ # if 'children' in config:
+ # for j, cpe_or_node in enumerate(config['children']):
+ # if "OR" == cpe_or_node['operator']:
+ # v.cpe_list += nist_scan_configuration_or(v,cpe_or_node, CVE_data_meta, j)
+ # else:
+ # print("ERROR CONFIGURE:OR_OP?:%s" % cpe_or_node['operator'])
+ # elif "OR" == config['operator']:
+ # v.cpe_list += nist_scan_configuration_or(v,config, CVE_data_meta, 0)
+ # else:
+ # print("ERROR CONFIGURE:OP?:%s" % config_rec['operator'])
+ # v.cpe_list += '[/and]|'
+ # v.cpe_list += '[/config]|'
+
+
+ #check if cve object `v` need to be uploaded to database (cases: new cve, modified cve, or no changes)
+ #if true, apply changes. Else ignore and continue
+ v_id, is_change = sql_cve_query(conn, v, log)
+
+
+ #if CVE `v` updates, must check and update associated records (CWEs, references, and CVE2CWE)
+ #sql_reference_query, sql_cwe_query, and sql_cve2cwe_query require valid CVE record primary key at some point during their execution, therefore must always be after call to sql_cve_query
+ if is_change:
+ r = Reference()
+ for ref in references:
+ r.cve_id = v_id
+ r.hyperlink = ref['url']
+ sql_reference_query(conn, r)
+
+ problem_list = cve['problemtype']['problemtype_data']
+ for problem_Item in problem_list:
+ description_list = problem_Item['description']
+ for description_Item in description_list:
+ value = description_Item['value']
+ cwe_id = sql_cwe_query(conn, value)
+ sql_cve2cwe_query(conn, v_id, cwe_id)
+
+ except Exception as e:
+ print(traceback.format_exc())
+ print("UPDATE FAILED")
+ c.close()
+ conn.close()
+ return
+ print()
+ log.write("total number of CVEs checked: %s\n" % total)
+ conn.commit()
+ c.close()
+ conn.close()
+
+#################################
+# cve class
+#
+class Cve():
+ # WR Status
+ NEW = 0
+ EXCLUDE = 1
+ INVESTIGATE = 2
+ VULNERABLE = 3
+ NOT_VULNERABLE = 4
+ STATUS = (
+ (NEW, 'New'),
+ (EXCLUDE, 'Exclude'),
+ (INVESTIGATE, 'Investigate'),
+ (VULNERABLE, 'Vulnerable'),
+ (NOT_VULNERABLE, 'Not Vulnerable'),
+ )
+
+ # Publish options
+ PUBLISH_UNPUBLISHED = 0
+ PUBLISH_NOPUBLISH = 1
+ PUBLISH_PUBLISHED = 2
+ PUBLISH_REQUEST = 3
+ PUBLISH_UPDATE = 4
+ PUBLISH_SUBMITTED = 5
+
+ # index - primary key
+ id = -1
+
+ name = ''
+ datasource = 0
+
+ source = ''
+ priority = 0
+ status = NEW
+
+ comments = ''
+ comments_private = ''
+
+ cve_data_type = ''
+ cve_data_format = ''
+ cve_data_version = ''
+
+ public = False
+ publish_state = PUBLISH_UNPUBLISHED
+ publish_date = ''
+
+ description = ''
+ publishedDate = ''
+ lastModifiedDate = ''
+ problemtype = ''
+
+ # cpe_list = ''
+
+ cvssV3_baseScore = ''
+ cvssV3_baseSeverity = ''
+ # cvssV3_vectorString = ''
+ # cvssV3_exploitabilityScore = ''
+ # cvssV3_impactScore = ''
+ # cvssV3_attackVector = ''
+ # cvssV3_attackComplexity = ''
+ # cvssV3_privilegesRequired = ''
+ # cvssV3_userInteraction = ''
+ # cvssV3_scope = ''
+ # cvssV3_confidentialityImpact = ''
+ # cvssV3_integrityImpact = ''
+ # cvssV3_availabilityImpact = ''
+
+ cvssV2_baseScore = ''
+ cvssV2_severity = ''
+ # cvssV2_vectorString = ''
+ # cvssV2_exploitabilityScore = ''
+ # cvssV2_impactScore = ''
+ # cvssV2_accessVector = ''
+ # cvssV2_accessComplexity = ''
+ # cvssV2_authentication = ''
+ # cvssV2_confidentialityImpact = ''
+ # cvssV2_integrityImpact = ''
+
+ recommend = 0
+ recommend_list = []
+
+ #generates importance score based on key-words in description of CVE, higher indicates more important
+ def recommendation(self):
+ description = ' '+self.description.lower()+' '
+ total = 0
+ list = ''
+
+ for keypair in keywords_for:
+ #print("keypair='%s'" % keypair)
+ key,w = keypair.split(',')
+ weight = 1
+# if w:
+# weight = int(w)
+ #if ' '+key+' ' in description:
+ if re.search(r'\b%s\b' % key, description):
+ list += ",+%s" % key
+ total += weight
+
+ for keypair in keywords_against:
+ #print("keypair='%s'" % keypair)
+ key,w = keypair.split(',')
+ weight = 1
+# if w:
+# weight = int(w)
+ # re.search(r'\bis\b', your_string)
+ #if ' '+key+' ' in description:
+ #if re.search(re.escape(r'\b%s\b' % key), description):
+ if re.search(r'\b%s\b' % key, description):
+ list += ",-%s" % key
+ total -= weight
+
+ # set filter maximums
+ if total < -3:
+ total = -3
+ if total > 3:
+ total = 3
+ self.recommend = total
+ self.recommend_list = list[1:]
+
+#generates and executes appropriate SQLite query for CVE depending on situation
+#new CVE -> INSERT || modified CVE -> UPDATE || no change -> ignore and return
+#returns (CVE_ID, BOOL) tuple, True if insert or update executed
+### THIS DOES NOT CALL CONNECTION.COMMIT()
+def sql_cve_query(conn, cve, log):
+ CVE_LASTMODIFIEDDATE = 14
+ is_change = False
+ cur = conn.cursor()
+ sql = '''SELECT * FROM orm_cve WHERE name=?'''
+ exists = cur.execute(sql, (cve.name,)).fetchone()
+ cve_id = -1
+ if exists is None:
+ cve.recommendation()
+ sql = ''' INSERT into orm_cve (name, source, datasource_id, priority, status, comments, comments_private, cve_data_type, cve_data_format, cve_data_version, public, publish_state, publish_date, description, publishedDate, lastModifiedDate, recommend, recommend_list, cvssV3_baseScore, cvssV3_baseSeverity, cvssV2_baseScore, cvssV2_severity)
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'''
+ cur.execute(sql, (cve.name, cve.source, cve.datasource, cve.priority, cve.status, cve.comments, cve.comments_private, cve.cve_data_type, cve.cve_data_format, cve.cve_data_version, 1, cve.publish_state, cve.publish_date, cve.description, cve.publishedDate, cve.lastModifiedDate, cve.recommend, cve.recommend_list, cve.cvssV3_baseScore, cve.cvssV3_baseSeverity, cve.cvssV2_baseScore, cve.cvssV2_severity))
+ is_change = True
+ cve_id = cur.lastrowid
+ log.write("\tINSERTED '%s'\n" % cve.name)
+ elif exists[CVE_LASTMODIFIEDDATE] < cve.lastModifiedDate:
+ cve.recommendation()
+ sql = ''' UPDATE orm_cve
+ SET source = ?,
+ recommend = ?,
+ recommend_list = ?,
+ cve_data_type = ?,
+ cve_data_format = ?,
+ cve_data_version = ?,
+ description = ?,
+ lastModifiedDate = ?,
+ cvssV3_baseScore = ?,
+ cvssV3_baseSeverity = ?,
+ cvssV2_baseScore = ?,
+ cvssV2_severity = ?
+ WHERE id = ?'''
+ cur.execute(sql, (cve.source, cve.recommend, cve.recommend_list, cve.cve_data_type, cve.cve_data_format, cve.cve_data_version, cve.description, cve.lastModifiedDate, cve.cvssV3_baseScore, cve.cvssV3_baseSeverity, cve.cvssV2_baseScore, cve.cvssV2_severity, exists[0]))
+ is_change = True
+ log.write("\tUPDATED '%s'\n" % cve.name)
+ cve_id = exists[0]
+ else:
+ is_change = False
+ log.write("\tSKIPPED '%s'\n" % cve.name)
+ cur.close()
+ return (cve_id, is_change)
+
+
+#################################
+# reference
+#
+class Reference():
+ cve_id = -1
+ hyperlink = ''
+ resource = ''
+ type_ = ''
+ source = ''
+ name = ''
+
+#generates and executes appropriate SQLite query for a new reference
+### THIS DOES NOT CALL CONNECTION.COMMIT()
+def sql_reference_query(conn, ref):
+ cur = conn.cursor()
+ sql = '''SELECT 1 FROM orm_cvereference WHERE hyperlink=?'''
+ record = cur.execute(sql, (ref.hyperlink,)).fetchone()
+ if record is None:
+ sql = '''INSERT INTO orm_cvereference (cve_id, hyperlink) VALUES (?, ?)'''
+ cur.execute(sql, (ref.cve_id, ref.hyperlink))
+ cur.close()
+
+#################################
+# cwe and cve2cwe
+#
+
+#generates and executes appropriate SQLite query for a new CWE
+#returns CWE_ID
+### THIS DOES NOT CALL CONNECTION.COMMIT()
+def sql_cwe_query(conn, value):
+ cur = conn.cursor()
+ sql = '''SELECT 1 FROM orm_cwetable WHERE name=?'''
+ cwe = cur.execute(sql, (value,)).fetchone()
+ if cwe is None:
+ sql = '''INSERT INTO orm_cwetable (name, name_sort, href, summary, description, vulnerable_count, found) VALUES (?,'','','','',1,1)'''
+ cur.execute(sql, (value,))
+ cwe = cur.lastrowid
+ cur.close()
+ return cwe
+ cur.close()
+ return cwe[0]
+
+#generates and executes appropriate SQLite query for new CVE to CWE relation
+### THIS DOES NOT CALL CONNECTION.COMMIT()
+def sql_cve2cwe_query(conn, cve_id, cwe_id):
+ cur = conn.cursor()
+ sql = '''SELECT * FROM orm_cvetocwe WHERE cve_id=? AND cwe_id=?'''
+ cve2cwe = cur.execute(sql, (cve_id, cwe_id))
+ if cve2cwe is None:
+ sql = '''INSERT INTO orm_cvetocwe (cve_id, cwe_id) VALUES (?, ?)'''
+ cur.execute(sql, (cve_id, cwe_id))
+ cur.close()
+
+#################################
+# main loop
+#
+
+def main(argv):
+ parser = argparse.ArgumentParser(description='srtool_cve.py: manage the CVEs within SRTool database')
+
+ parser.add_argument('--update_nist', '-n', nargs=1, help='Check nvd.nist.gov/vuln/data-feeds for updates on a specified datasource')
+ parser.add_argument('--update_nist_incremental', '-i', action='store_const', const='update_nist_incremental', dest='command', help='Check nvd.nist.gov/vuln/data-feeds for updates')
+ args = parser.parse_args()
+
+ master_log = open(os.path.join(SRT_BASE_DIR, "update_logs/master_log.txt"), "a")
+
+ if args.update_nist:
+ try:
+ print ("BEGINNING NIST UPDATES PLEASE WAIT ... this can take some time")
+ update_nist(args.update_nist[0], False)
+ master_log.write("SRTOOL:%s:%s:\t\t\t...\t\t\tUPDATED\n" % (date.today(), args.update_nist[0]))
+ print("DATABASE UPDATE FINISHED\n")
+ except Exception as e:
+ print("DATABASE UPDATED FAILED ... %s" % e)
+ master_log.write("SRTOOL:%s:%s:\t\t\t...\t\t\tFAILED ... %s\n" % (date.today(), args.update_nist[0], e))
+ elif 'update_nist_incremental' == args.command:
+ try:
+ print ("BEGINNING NIST UPDATES PLEASE WAIT ... this can take some time")
+ update_nist('NIST JSON Modified Data', True)
+ master_log.write("SRTOOL:%s:'NIST JSON Modified Data':\t\t\t...\t\t\tUPDATED\n" % date.today())
+ print("DATABASE UPDATE FINISHED\n")
+ except Exception as e:
+ print("DATABASE UPDATED FAILED ... %s" % e)
+ master_log.write("SRTOOL:%s:%s:\t\t\t...\t\t\tFAILED ... %s\n" % (date.today(), 'NIST JSON Modified Data', e))
+
+ else:
+ print("Command not found")
+ master_log.close()
+
+if __name__ == '__main__':
+ global SRT_BASE_DIR
+ from os.path import abspath
+ # fetch any environment overrides
+ set_override('SRTDBG_SKIP_CVE_IMPORT')
+ set_override('SRTDBG_MINIMAL_DB')
+ if get_override('SRTDBG_SKIP_CVE_IMPORT'):
+ exit(0)
+
+ SRT_BASE_DIR = os.path.abspath(os.path.dirname(os.path.dirname(sys.argv[0])))
+
+ main(sys.argv[1:])