-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
141 lines (129 loc) · 5.24 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import json, os
import datetime
import argparse
import dicttoxml
import subprocess
import xml.etree.ElementTree as ET
import shutil
from xml.dom.minidom import parseString
from Parsers.conanParser import conanParser
from Parsers.dartParser import dartParser
from Parsers.dotnetParser import dotnetParser
from Parsers.gradleGroovyParser import gradleGroovyParser
from Parsers.gradlekotlinDSLParser import gradlekotlinDSLParser
from Parsers.mavenParser import mavenParser
from Parsers.npmParser import npmParser
from Parsers.phpParser import phpParser
from Parsers.rustParser import rustParser
from Parsers.swiftParser import swiftParser
from Parsers.yarnParser import YarnParser
from Parsers.rubyParser import rubyparser
from Parsers.requirementsParser import requirementsParser
from Parsers.gomodParser import goModParser
from Utility.helpers import get_project_path
from Utility.dependencyTree import DependencyTree
from Utility.zip import zip_extract
def createSbom(path):
projname = os.path.split(path)[-1]
sbom = {
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": "1",
"metadata": {
"timestamp": datetime.datetime.now().isoformat(),
"component": {
"group": "",
"name": projname,
"version": "0.0.0",
"type": "application",
},
},
"components": [],
"services": [],
"dependencies": [],
}
phpParser(path, sbom)
npmParser(path, sbom)
YarnParser(path, sbom)
requirementsParser(path, sbom)
conanParser(path, sbom)
dartParser(path, sbom)
dotnetParser(path, sbom)
gradleGroovyParser(path, sbom)
gradlekotlinDSLParser(path, sbom)
mavenParser(path, sbom)
rustParser(path, sbom)
swiftParser(path, sbom)
rubyparser(path,sbom)
goModParser(path,sbom)
return sbom
def createsbomJson(path):
output_path=os.path.join(path,'sbom.json')
if(os.path.split(path)[-1].split('.')[-1] == 'zip'):
output_path=os.path.join(os.path.dirname(path),'sbom.json')
path=zip_extract(path)
sbom = createSbom(path)
with open(output_path, "w", encoding="utf-8") as file:
json.dump(sbom, file, indent=4)
file.close()
return sbom
import xml.etree.ElementTree as ET
def createsbomXML(path):
output_path=os.path.join(path,'sbom.xml')
if(os.path.split(path)[-1].split('.')[-1] == 'zip'):
output_path=os.path.join(os.path.dirname(path),'sbom.xml')
path=zip_extract(path)
sbom = createSbom(path)
xmlStr = dicttoxml.dicttoxml(sbom)
dom = parseString(xmlStr)
prettyXML = dom.toprettyxml()
with open(output_path, "w") as file:
file.write(prettyXML)
return sbom
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Generate Software Bill of Materials (SBOM) for a project.')
parser.add_argument('-p', '--project_path', type=str, help='The path to the project')
parser.add_argument('-f', '--format', type=str, help='The output file format')
parser.add_argument('--vul', action='store_true', help='Include vulnerability information (yes/no)')
parser.add_argument('--tree', action='store_true', help='Generate dependency tree (yes/no)')
sbom={}
args = parser.parse_args()
output_file=''
user_input_report=''
treeFlag=False
if args.project_path:
user_input_path = args.project_path
if not os.path.isabs(user_input_path):
user_input_path = os.path.join(os.getcwd(), user_input_path)
project_path = user_input_path
else:
project_path, output_file, user_input_report, treeFlag= get_project_path()
output_file = f"sbom.{output_file}"
project_path = os.path.abspath(project_path)
if(output_file==""):
if args.format:
if args.format not in ['xml', 'json'] or args.format == 'json':
if args.format not in ['xml','json']:
print('Invalid output format\n\nGenerating in json')
output_file = 'sbom.json'
else :
output_file = f'sbom.{args.format}'
else:
output_file = 'sbom.json'
print("\n🚀 Generating SBOM...")
if output_file=='sbom.json':
sbom=createsbomJson(project_path)
else:
sbom = createsbomXML(project_path)
zipFlag=False
if(os.path.split(project_path)[-1].split('.')[-1] == 'zip'):
# shutil.rmtree(os.path.join(os.path.split(project_path)[0], os.path.splitext(os.path.basename(project_path))[0]), ignore_errors=True)
project_path=os.path.dirname(project_path)
zipFlag=True
if args.tree or treeFlag:
DependencyTree(sbom, project_path)
print(f"\n✅ SBOM generated successfully!")
print(f"📄 SBOM file is located at: {os.path.join(project_path, output_file)}")
if args.vul or user_input_report=='yes':
subprocess.run(["depscan", "--bom", os.path.join(project_path, output_file), "-o", os.path.join(project_path, "Report.html")], shell=True)
print(f"\n✅ Vulnerability Report generated successfully, Please take the necessary actions")