-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgitkeyfinder
executable file
·96 lines (78 loc) · 2.53 KB
/
gitkeyfinder
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
#!/usr/bin/python3
import argparse
import logging
import os
import shutil
import subprocess
import tempfile
import urllib
import pygit2
import keyfinder
ap = argparse.ArgumentParser()
ap.add_argument("repo", help="URL or local path of git repository")
ap.add_argument("--keep", action="store_true", help="Don't delete tmpdir")
ap.add_argument("-o", "--outdir", default="out", help="Output dir")
ap.add_argument("-D", "--dupfile", help="Store duplicate information")
ap.add_argument("--nobadkeys", action="store_true", help="Don't check with badkeys")
ap.add_argument("--log", help="Logfile")
args = ap.parse_args()
if args.log:
logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s",
filename=args.log, level=logging.INFO)
tmpdir = tempfile.mkdtemp(prefix="gitkf")
if args.dupfile and os.path.exists(args.dupfile):
keyfinder.load_dupfile(args.dupfile)
usebk = True
if args.nobadkeys:
usebk = False
shortd = {
"github.com": "hub",
"gitlab.com": "lab",
}
print(f"Looking for keys in {args.repo}")
if "://" in args.repo:
logging.info("Cloning repo %s", args.repo)
# Call git directly, as cloning with libgit2/pygit2 is
# very slow: https://github.com/libgit2/libgit2/issues/4674
subprocess.check_output(["git", "clone", args.repo, tmpdir])
rep = pygit2.Repository(tmpdir)
up = urllib.parse.urlparse(args.repo)
host = up.hostname
if up.hostname in shortd:
host = shortd[up.hostname]
outdir = f"{args.outdir}/{host}/{up.path}"
else:
rep = pygit2.Repository(args.repo)
outdir = args.outdir
logging.info("Checking repo object db")
dd = rep.odb
results = {}
for oid in dd:
o = rep.get(oid)
if isinstance(o, pygit2.Blob):
logging.info("Checking %s", oid)
keys = keyfinder.findkeys(o.read_raw(), usebk=usebk)
if keys:
results[str(oid)] = keys
print(f"found key(s) in {oid}")
logging.info("Finding filenames")
fnames = {}
for oid in dd:
o = rep.get(oid)
if isinstance(o, pygit2.Tree):
for x in o:
gid = str(x.id)
if gid in results and id not in fnames:
fnames[gid] = x.name
logging.info("Writing keys")
for gitid, v in results.items():
for spki, key in v.items():
fn = fnames.get(gitid, gitid)
prefix = f"id: {gitid}\n\n"
keyfinder.writekey(prefix + key, fn, outdir, spki)
if args.keep:
print(f"Git clone / tmpdir not removed: {tmpdir}")
else:
shutil.rmtree(tmpdir)
if args.dupfile:
keyfinder.write_dupfile(args.dupfile)