|
@@ -8,9 +8,9 @@ import (
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
"os"
|
|
"os"
|
|
|
"os/exec"
|
|
"os/exec"
|
|
|
|
|
+ "path"
|
|
|
"path/filepath"
|
|
"path/filepath"
|
|
|
"sync"
|
|
"sync"
|
|
|
- "path"
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
type Repo struct {
|
|
type Repo struct {
|
|
@@ -53,22 +53,28 @@ func newLocalRepo(repoPath string) *Repo {
|
|
|
|
|
|
|
|
func newRepo(name string, url string) *Repo {
|
|
func newRepo(name string, url string) *Repo {
|
|
|
repo := &Repo{
|
|
repo := &Repo{
|
|
|
- name: name,
|
|
|
|
|
- url: url,
|
|
|
|
|
|
|
+ name: name,
|
|
|
|
|
+ url: url,
|
|
|
// TODO handle existing one
|
|
// TODO handle existing one
|
|
|
- path: opts.ClonePath + "/" + name,
|
|
|
|
|
|
|
+ path: opts.ClonePath + "/" + name,
|
|
|
}
|
|
}
|
|
|
return repo
|
|
return repo
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (repo *Repo) rLog(msg string) {
|
|
|
|
|
|
|
+func (repo *Repo) Info(msg string) {
|
|
|
// logger should have these infos: msg, repo, owner, time
|
|
// logger should have these infos: msg, repo, owner, time
|
|
|
- logger.Debug("Beginning audit",
|
|
|
|
|
|
|
+ logger.Info(msg,
|
|
|
zap.String("repo", repo.name),
|
|
zap.String("repo", repo.name),
|
|
|
zap.String("repo_path", repo.path),
|
|
zap.String("repo_path", repo.path),
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func (repo *Repo) PrettyPrintF(format string, args ...interface{}) {
|
|
|
|
|
+ if opts.PrettyPrint {
|
|
|
|
|
+ fmt.Fprintf(os.Stderr, format, args...)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Audit operates on a single repo and searches the full or partial history of the repo.
|
|
// Audit operates on a single repo and searches the full or partial history of the repo.
|
|
|
// A semaphore is declared for every repo to bind concurrency. If unbounded, the system will throw a
|
|
// A semaphore is declared for every repo to bind concurrency. If unbounded, the system will throw a
|
|
|
// `too many open files` error. Eventually, gitleaks should use src-d/go-git to avoid shelling out
|
|
// `too many open files` error. Eventually, gitleaks should use src-d/go-git to avoid shelling out
|
|
@@ -84,7 +90,7 @@ func (repo *Repo) audit(owner *Owner) (bool, error) {
|
|
|
gitLeaksChan = make(chan Leak)
|
|
gitLeaksChan = make(chan Leak)
|
|
|
leaks []Leak
|
|
leaks []Leak
|
|
|
semaphoreChan = make(chan struct{}, opts.Concurrency)
|
|
semaphoreChan = make(chan struct{}, opts.Concurrency)
|
|
|
- leaksPst bool
|
|
|
|
|
|
|
+ leaksPst bool
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
dotGitPath := filepath.Join(repo.path, ".git")
|
|
dotGitPath := filepath.Join(repo.path, ".git")
|
|
@@ -96,13 +102,15 @@ func (repo *Repo) audit(owner *Owner) (bool, error) {
|
|
|
return false, fmt.Errorf("%s does not exist", repo.path)
|
|
return false, fmt.Errorf("%s does not exist", repo.path)
|
|
|
}
|
|
}
|
|
|
// no repo present, clone it
|
|
// no repo present, clone it
|
|
|
- fmt.Printf("Cloning \x1b[37;1m%s\x1b[0m into %s...\n", repo.url, repo.path)
|
|
|
|
|
|
|
+ repo.Info("cloning")
|
|
|
|
|
+ repo.PrettyPrintF("Cloning \x1b[37;1m%s\x1b[0m...\n", repo.url)
|
|
|
err = exec.Command("git", "clone", repo.url, repo.path).Run()
|
|
err = exec.Command("git", "clone", repo.url, repo.path).Run()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return false, fmt.Errorf("cannot clone %s into %s", repo.url, repo.path)
|
|
return false, fmt.Errorf("cannot clone %s into %s", repo.url, repo.path)
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- fmt.Printf("Checking \x1b[37;1m%s\x1b[0m from %s...\n", repo.url, repo.path)
|
|
|
|
|
|
|
+ repo.Info("fetching")
|
|
|
|
|
+ repo.PrettyPrintF("Fetching \x1b[37;1m%s\x1b[0m...\n", repo.url)
|
|
|
err = exec.Command("git", "fetch").Run()
|
|
err = exec.Command("git", "fetch").Run()
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return false, fmt.Errorf("cannot fetch %s from %s", repo.url, repo.path)
|
|
return false, fmt.Errorf("cannot fetch %s from %s", repo.url, repo.path)
|
|
@@ -141,7 +149,7 @@ func (repo *Repo) audit(owner *Owner) (bool, error) {
|
|
|
go reportAggregator(&gitLeakReceiverWG, gitLeaksChan, &leaks)
|
|
go reportAggregator(&gitLeakReceiverWG, gitLeaksChan, &leaks)
|
|
|
commitWG.Wait()
|
|
commitWG.Wait()
|
|
|
gitLeakReceiverWG.Wait()
|
|
gitLeakReceiverWG.Wait()
|
|
|
- if len(leaks) != 0{
|
|
|
|
|
|
|
+ if len(leaks) != 0 {
|
|
|
leaksPst = true
|
|
leaksPst = true
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -170,7 +178,7 @@ func (repo *Repo) writeReport() error {
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- fmt.Printf("Report written to %s\n", reportFile)
|
|
|
|
|
|
|
+ repo.Info(fmt.Sprintf("Report written to %s\n", reportFile))
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -201,13 +209,26 @@ func parseRevList(revList [][]byte) []Commit {
|
|
|
// reportAggregator is a go func responsible for ...
|
|
// reportAggregator is a go func responsible for ...
|
|
|
func reportAggregator(gitLeakReceiverWG *sync.WaitGroup, gitLeaks chan Leak, leaks *[]Leak) {
|
|
func reportAggregator(gitLeakReceiverWG *sync.WaitGroup, gitLeaks chan Leak, leaks *[]Leak) {
|
|
|
for gitLeak := range gitLeaks {
|
|
for gitLeak := range gitLeaks {
|
|
|
- b, err := json.MarshalIndent(gitLeak, "", " ")
|
|
|
|
|
- if err != nil {
|
|
|
|
|
- // make waitgroup errArray
|
|
|
|
|
- fmt.Println("failed to output leak:", err)
|
|
|
|
|
- }
|
|
|
|
|
- fmt.Println(string(b))
|
|
|
|
|
|
|
+ logger.Info("leak",
|
|
|
|
|
+ zap.String("line", gitLeak.Line),
|
|
|
|
|
+ zap.String("commit", gitLeak.Commit),
|
|
|
|
|
+ zap.String("offender", gitLeak.Offender),
|
|
|
|
|
+ zap.String("Reason", gitLeak.Reason),
|
|
|
|
|
+ zap.String("author", gitLeak.Author),
|
|
|
|
|
+ zap.String("file", gitLeak.File),
|
|
|
|
|
+ zap.String("repoURL", gitLeak.RepoURL),
|
|
|
|
|
+ zap.String("timeOfCommit", gitLeak.Time),
|
|
|
|
|
+ )
|
|
|
*leaks = append(*leaks, gitLeak)
|
|
*leaks = append(*leaks, gitLeak)
|
|
|
|
|
+ if opts.PrettyPrint {
|
|
|
|
|
+ b, err := json.MarshalIndent(gitLeak, "", " ")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ // handle this?
|
|
|
|
|
+ fmt.Println("failed to output leak:", err)
|
|
|
|
|
+ }
|
|
|
|
|
+ fmt.Println(string(b))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
gitLeakReceiverWG.Done()
|
|
gitLeakReceiverWG.Done()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|