# # BitBake Toaster Implementation # # Copyright (C) 2016-2018 Intel Corporation # # 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. # Please run flake8 on this file before sending patches import os import sys import logging import subprocess from django.http import JsonResponse logger = logging.getLogger("srt") def error_response(error): return JsonResponse({"error": error}) # quick development/debugging support def _log(msg): DBG_LVL = os.environ['SRTDBG_LVL'] if ('SRTDBG_LVL' in os.environ) else 2 DBG_LOG = os.environ['SRTDBG_LOG'] if ('SRTDBG_LOG' in os.environ) else '/tmp/srt_dbg.log' if 1 == DBG_LVL: print(msg) elif 2 == DBG_LVL: f1=open(DBG_LOG, 'a') f1.write("|" + msg + "|\n" ) f1.close() # Sub Process calls def execute_process(*args): cmd_list = [] for arg in args: if isinstance(arg, (list, tuple)): # Flatten all the way down for a in arg: cmd_list.append(a) else: cmd_list.append(arg) # Python < 3.5 compatible if sys.version_info < (3,5): process = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: stdout, stderr = process.communicate(input) except: process.kill() process.wait() raise retcode = process.poll() return retcode, stdout, stderr else: result = subprocess.run(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.PIPE) return result.returncode,result.stdout,result.stderr # # Extract Upstream CVE record details # def readCveDetails_Upstream(cve, cve_datasource): from orm.models import CveDetail # Initialize and populate CveDetail object to return v = CveDetail() v.name = cve.name # Get the object lookup_command = cve_datasource.lookup if not lookup_command: v.description = "ERROR(%s):missing lookup command" % (cve_datasource.description) return v lookup_command = lookup_command.replace('%command%','--cve-detail=%s' % cve.name) result_returncode,result_stdout,result_stderr = execute_process(lookup_command.split(' ')) #_log("SRT_%s=%s|%s|%s" % (cve_datasource.key,result_returncode,result_stdout,result_stderr)) if 0 != result_returncode: result_stdout = str(result_stdout) v.description = "ERROR(%s):%s" % (result_returncode,result_stderr) return v for line in result_stdout.decode("utf-8").splitlines(): try: name = line[:line.index('=')] value = line[line.index('=')+1:].replace("[EOL]","\n") except: continue if name == 'cve_data_type': v.cve_data_type = value elif name == 'cve_data_format': v.cve_data_format = value elif name == 'cve_data_version': v.cve_data_version = value elif name == 'description': v.description = value elif name == 'publishedDate': v.publishedDate = value elif name == 'lastModifiedDate': v.lastModifiedDate = value elif name == 'url': v.url = value elif name == 'url_title': v.url_title = value elif name == 'cvssV3_baseScore': v.cvssV3_baseScore = value elif name == 'cvssV3_baseSeverity': v.cvssV3_baseSeverity = value elif name == 'cvssV3_vectorString': v.cvssV3_vectorString = value elif name == 'cvssV3_exploitabilityScore': v.cvssV3_exploitabilityScore = value elif name == 'cvssV3_impactScore': v.cvssV3_impactScore = value elif name == 'cvssV3_attackVector': v.cvssV3_attackVector = value elif name == 'cvssV3_attackComplexity': v.cvssV3_attackComplexity = value elif name == 'cvssV3_privilegesRequired': v.cvssV3_privilegesRequired = value elif name == 'cvssV3_userInteraction': v.cvssV3_userInteraction = value elif name == 'cvssV3_scope': v.cvssV3_scope = value elif name == 'cvssV3_confidentialityImpact': v.cvssV3_confidentialityImpact = value elif name == 'cvssV3_integrityImpact': v.cvssV3_integrityImpact = value elif name == 'cvssV3_availabilityImpact': v.cvssV3_availabilityImpact = value elif name == 'cvssV2_baseScore': v.cvssV2_baseScore = value elif name == 'cvssV2_severity': v.cvssV2_severity = value elif name == 'cvssV2_vectorString': v.cvssV2_vectorString = value elif name == 'cvssV2_exploitabilityScore': v.cvssV2_exploitabilityScore = value elif name == 'cvssV2_impactScore': v.cvssV2_impactScore = value elif name == 'cvssV2_accessVector': v.cvssV2_accessVector = value elif name == 'cvssV2_accessComplexity': v.cvssV2_accessComplexity = value elif name == 'cvssV2_authentication': v.cvssV2_authentication = value elif name == 'cvssV2_confidentialityImpact': v.cvssV2_confidentialityImpact = value elif name == 'cvssV2_integrityImpact': v.cvssV2_integrityImpact = value elif name == 'cpe_list': v.cpe_list = value #_log("cpe_list:%s:%s:" % (cve.name,value)) elif name == 'ref_list': v.ref_list = value return v # # Extract Local CVE record details # def readCveDetails_Local(cve,cve_datasource): from orm.models import CveLocal, CveDetail # Initialize and populate CveDetail object to return v = CveDetail() v.name = cve.name # Get the CveLocal object v_local = CveLocal.objects.get(name=cve.name) # v.description = v_local.description v.publishedDate = v_local.publishedDate v.lastModifiedDate = v_local.lastModifiedDate v.url = v_local.url v.url_title = v_local.url_title v.cve_data_type = v_local.cve_data_type v.cve_data_format = v_local.cve_data_format v.cve_data_version = v_local.cve_data_version # v.cvssV3_baseScore = v_local.cvssV3_baseScore v.cvssV3_baseSeverity = v_local.cvssV3_baseSeverity v.cvssV3_vectorString = v_local.cvssV3_vectorString v.cvssV3_exploitabilityScore = v_local.cvssV3_exploitabilityScore v.cvssV3_impactScore = v_local.cvssV3_impactScore v.cvssV3_attackVector = v_local.cvssV3_attackVector v.cvssV3_attackComplexity = v_local.cvssV3_attackComplexity v.cvssV3_privilegesRequired = v_local.cvssV3_privilegesRequired v.cvssV3_userInteraction = v_local.cvssV3_userInteraction v.cvssV3_scope = v_local.cvssV3_scope v.cvssV3_confidentialityImpact = v_local.cvssV3_confidentialityImpact v.cvssV3_integrityImpact = v_local.cvssV3_integrityImpact v.cvssV3_availabilityImpact = v_local.cvssV3_availabilityImpact # v.cvssV2_baseScore = v_local.cvssV2_baseScore v.cvssV2_severity = v_local.cvssV2_severity v.cvssV2_vectorString = v_local.cvssV2_vectorString v.cvssV2_exploitabilityScore = v_local.cvssV2_exploitabilityScore v.cvssV2_impactScore = v_local.cvssV2_impactScore v.cvssV2_accessVector = v_local.cvssV2_accessVector v.cvssV2_accessComplexity = v_local.cvssV2_accessComplexity v.cvssV2_authentication = v_local.cvssV2_authentication v.cvssV2_confidentialityImpact = v_local.cvssV2_confidentialityImpact v.cvssV2_integrityImpact = v_local.cvssV2_integrityImpact # v.cpe_list = v.cpe_list return v def readCveDetails_None(cve): from orm.models import CveDetail # Initialize and populate CveDetail object to return v = CveDetail() v.name = cve.name v.cve_data_type = "None" v.description = cve.description v.cvssV3_baseScore = cve.cvssV3_baseScore v.cvssV3_baseSeverity = cve.cvssV3_baseSeverity v.cvssV2_baseScore = cve.cvssV2_baseScore v.cvssV2_severity = cve.cvssV2_severity return v def readCveDetails(cve,cve_datasource): if None == cve_datasource: return readCveDetails_None(cve) elif "Local" == cve_datasource.name: return readCveDetails_Local(cve,cve_datasource) else: return readCveDetails_Upstream(cve,cve_datasource) def writeCveDetails(cve_name,request): from orm.models import Cve, CveLocal, CveSource cve_local = CveLocal.objects.get(name=cve_name) # cve_local.description = request.POST.get('description' ,cve_local.description) cve_local.lastModifiedDate = request.POST.get('lastModifiedDate' ,cve_local.lastModifiedDate) cve_local.publishedDate = request.POST.get('publishedDate' ,cve_local.publishedDate) cve_local.url = request.POST.get('url' ,cve_local.url) cve_local.url_title = request.POST.get('url_title' ,cve_local.url) cve_local.cve_data_type = request.POST.get('cve_data_type' ,cve_local.cve_data_type) cve_local.cve_data_format = request.POST.get('cve_data_format' ,cve_local.cve_data_format) cve_local.cve_data_version = request.POST.get('cve_data_version' ,cve_local.cve_data_version) # cve_local.cvssV3_baseScore = request.POST.get('cvssV3_baseScore' ,cve_local.cvssV3_baseScore) cve_local.cvssV3_baseSeverity = request.POST.get('cvssV3_baseSeverity' ,cve_local.cvssV3_baseSeverity) cve_local.cvssV3_vectorString = request.POST.get('cvssV3_vectorString' ,cve_local.cvssV3_vectorString) cve_local.cvssV3_exploitabilityScore = request.POST.get('cvssV3_exploitabilityScore' ,cve_local.cvssV3_exploitabilityScore) cve_local.cvssV3_impactScore = request.POST.get('cvssV3_impactScore' ,cve_local.cvssV3_impactScore) cve_local.cvssV3_attackVector = request.POST.get('cvssV3_attackVector' ,cve_local.cvssV3_attackVector) cve_local.cvssV3_attackComplexity = request.POST.get('cvssV3_attackComplexity' ,cve_local.cvssV3_attackComplexity) cve_local.cvssV3_privilegesRequired = request.POST.get('cvssV3_privilegesRequired' ,cve_local.cvssV3_privilegesRequired) cve_local.cvssV3_userInteraction = request.POST.get('cvssV3_userInteraction' ,cve_local.cvssV3_userInteraction) cve_local.cvssV3_scope = request.POST.get('cvssV3_scope' ,cve_local.cvssV3_scope) cve_local.cvssV3_confidentialityImpact = request.POST.get('cvssV3_confidentialityImpact' ,cve_local.cvssV3_confidentialityImpact) cve_local.cvssV3_integrityImpact = request.POST.get('cvssV3_integrityImpact' ,cve_local.cvssV3_integrityImpact) cve_local.cvssV3_availabilityImpact = request.POST.get('cvssV3_availabilityImpact' ,cve_local.cvssV3_availabilityImpact) # cve_local.cvssV2_baseScore = request.POST.get('cvssV2_baseScore' ,cve_local.cvssV2_baseScore) cve_local.cvssV2_severity = request.POST.get('cvssV2_severity' ,cve_local.cvssV2_severity) cve_local.cvssV2_vectorString = request.POST.get('cvssV2_vectorString' ,cve_local.cvssV2_vectorString) cve_local.cvssV2_exploitabilityScore = request.POST.get('cvssV2_exploitabilityScore' ,cve_local.cvssV2_exploitabilityScore) cve_local.cvssV2_impactScore = request.POST.get('cvssV2_impactScore' ,cve_local.cvssV2_impactScore) cve_local.cvssV2_accessVector = request.POST.get('cvssV2_accessVector' ,cve_local.cvssV2_accessVector) cve_local.cvssV2_accessComplexity = request.POST.get('cvssV2_accessComplexity' ,cve_local.cvssV2_accessComplexity) cve_local.cvssV2_authentication = request.POST.get('cvssV2_authentication' ,cve_local.cvssV2_authentication) cve_local.cvssV2_confidentialityImpact = request.POST.get('cvssV2_confidentialityImpact' ,cve_local.cvssV2_confidentialityImpact) cve_local.cvssV2_integrityImpact = request.POST.get('cvssV2_integrityImpact' ,cve_local.cvssV2_integrityImpact) # cve_local.cpe_list = request.POST.get('cpe_list' ,cve_local.cpe_list) cve_local.save() # If this is a pure local Cve (not an edit overlay) then update main Cve cve = Cve.objects.get(name=cve_local.name) cve_sources = CveSource.objects.filter(cve=cve) cve.description = cve_local.description if 1 == len(cve_sources): # Skip the status values, since they have a specific editor # ? lastModifiedDate # ? recommend # ? recommend_list pass cve.save() def summaryCveDetails(cve,cve_sources): from orm.models import CveLocal, CveDetail cve_detail = CveDetail() cve_local = None cve_main = None def summaryMerge(cve_detail,cve_main,cve_local,cve_html,attr_name): if cve_local and getattr(cve_local, attr_name): setattr(cve_detail, attr_name, getattr(cve_local, attr_name)) # WARNING: something in Django adds the quotes around the style value, so do not add them here cve_html[attr_name] = " style=color:blue;" else: setattr(cve_detail, attr_name, getattr(cve_main, attr_name)) cve_html[attr_name] = '' for cs in cve_sources: if 'Local' == cs.datasource.name: cve_local = CveLocal.objects.get(name=cve.name) elif None == cve_main: cve_main = readCveDetails(cve,cs.datasource) if None == cve_main: # Single local summary cve_main = cve_local # Merge the CVE details cve_detail.name = cve.name cve_html = {} summaryMerge(cve_detail,cve_main,cve_local,cve_html,'description') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cve_data_format') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'lastModifiedDate') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'publishedDate') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'url') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'url_title') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_baseScore') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_baseSeverity') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_vectorString') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_exploitabilityScore') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_impactScore') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_attackVector') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_attackComplexity') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_privilegesRequired') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_userInteraction') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_scope') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_confidentialityImpact') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_integrityImpact') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV3_availabilityImpact') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_baseScore') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_severity') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_vectorString') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_exploitabilityScore') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_impactScore') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_accessVector') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_accessComplexity') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_authentication') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_confidentialityImpact') summaryMerge(cve_detail,cve_main,cve_local,cve_html,'cvssV2_integrityImpact') ### TODO: INTELIGENT CPE_LIST MERGE cve_detail.cpe_list = cve_main.cpe_list cve_detail.ref_list = cve_main.ref_list return cve_detail,cve_html