-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsherlock.py
More file actions
108 lines (91 loc) · 5.1 KB
/
Copy pathsherlock.py
File metadata and controls
108 lines (91 loc) · 5.1 KB
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
import argparse
import subprocess
import sys
import helpers.crate_data as crate_data
from helpers.assumption import CrateVersion
from pprint import pprint
from helpers.logger import get_latest_version,verify_version
import json
import os
def main():
parser = argparse.ArgumentParser(description='Rust Holmes Sherlock: A tool to analye Rust crates')
subparsers = parser.add_subparsers(dest='command', help='Subcommands (log, trust)')
# Subcommand for logging information
log_parser = subparsers.add_parser('log', help='Get logging information about a crate')
log_parser.add_argument('crate_name', type=str, help='Name of the crate')
log_parser.add_argument('version', type=str, nargs='?', default=None, help='Version of the crate (optional)')
log_parser.add_argument('-u', '--update', action='store_true', help='Update information by running scrapper.py, getCrates.py, and aggregator.py')
log_parser.add_argument('-o', '--output', type=str, help='Output file path to save crate information')
log_parser.add_argument('-p', '--path', type=str, help='Path to the local crate source code (optional)')
# Subcommand for trust score
trust_parser = subparsers.add_parser('trust', help='Solve using assumptions to assign a trust score to the crate')
trust_parser.add_argument('crate_name', type=str, help='Name of the crate')
trust_parser.add_argument('version', type=str, nargs='?', default=None, help='Version of the crate (optional)')
trust_parser.add_argument('-o', '--output', type=str, help='Output file path to save trust score information')
trust_parser.add_argument('--no-horn', action='store_true', help='Use the naive solver instead of the Horn solver; not recommended for large crates')
trust_parser.add_argument('-p', '--path', type=str, help='Path to the local crate source code (optional)')
args = parser.parse_args()
if args.command is None:
parser.print_help()
sys.exit(0)
# Fetch the latest version if not provided
if args.version is None:
if args.path is None:
print(f"Version not specified, fetching the Latest version for analysis.")
args.version = get_latest_version(args.crate_name)
print(f"Latest version of {args.crate_name} is {args.version}.")
else:
print(f"Version not specified, assuming version to be 1.0.0 for local crate analysis.")
args.version = "1.0.0"
else:
if args.path is None: # we want to verify version only for published crates
if not verify_version(args.crate_name, args.version):
sys.exit(1)
# Handle the 'log' subcommand
if args.command == 'log':
if args.update:
print("Updating information...")
print("Running scrapper.py to collect information from the RUST SEC website...")
subprocess.run([sys.executable, 'scrapper.py'])
print("Running getCrates.py to get all crates and their side effects...")
subprocess.run([sys.executable, 'getCrates.py'])
print("Running aggregator.py to get the side effects for all reported vulnerable functions...")
subprocess.run([sys.executable, 'aggregator.py'])
# Get logging information about the crate
crate = CrateVersion(args.crate_name, args.version)
print(f"Getting logging information About crate {crate}...")
if args.path:
crate_information = crate_data.get_crate_metadata(crate, local=args.path)
else:
crate_information = crate_data.get_crate_metadata(crate)
print(f"Logging information for {args.crate_name}-{args.version}:")
pprint(crate_information)
# Save crate information to the output file if provided
if args.output:
temp = dict(crate_information)
# save the audit summary to a cache file
with open(args.output, "w") as file:
json.dump(temp, file, indent=2)
print(f"Crate information saved to {args.output}.")
elif args.command == 'trust':
from solver import complete_analysis
use_horn_solver = not args.no_horn
crate = CrateVersion(args.crate_name, args.version)
if not args.path:
args.path = False
else:
# validate the path exists, it should be an absolute path
result = os.path.isabs(args.path)
if not result:
print(f"The provided path {args.path} is not an absolute path.")
sys.exit(1)
# If output is provided, open the file; otherwise, print to console
if args.output:
with open(args.output, 'w') as output_file:
print(f"Solving for required assumptions to trust {crate}...", file=output_file)
complete_analysis(crate, horn_solver = use_horn_solver, file = output_file, local = args.path)
else:
print(f"Solving for required assumptions to trust {crate}...")
complete_analysis(crate, horn_solver = use_horn_solver, file = sys.stdout, local = args.path)
if __name__ == "__main__":
main()