yarascanner/git.go

79 lines
1.5 KiB
Go

package main
import (
"github.com/hillu/go-yara/v4"
"github.com/package-url/packageurl-go"
"gopkg.in/src-d/go-git.v4"
"gopkg.in/src-d/go-git.v4/plumbing"
"gopkg.in/src-d/go-git.v4/plumbing/object"
"gopkg.in/src-d/go-git.v4/storage/memory"
)
// Load rules from a git url.
// Supports github, bitbucket, gitlab, and regular git urls.
// Version will be interpreted as a commit hash
func loadRulesFromGit(pkg packageurl.PackageURL, c *yara.Compiler) error {
var repoUrl string
switch pkg.Type {
case "github":
repoUrl = "https://github.com/" + pkg.Namespace + "/" + pkg.Name
case "bitbucket":
repoUrl = "https://bitbucket.com/" + pkg.Namespace + "/" + pkg.Name
case "gitlab":
repoUrl = "https://gitlab.com/" + pkg.Namespace + "/" + pkg.Name
default:
repoUrl = "https://" + pkg.Namespace + "/" + pkg.Name
}
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: repoUrl,
})
if err != nil {
return err
}
var hash plumbing.Hash
if pkg.Version != "" {
hash = plumbing.NewHash(pkg.Version)
} else {
ref, err := r.Head()
if err != nil {
return err
}
hash = ref.Hash()
}
commit, err := r.CommitObject(hash)
if err != nil {
return err
}
tree, err := commit.Tree()
if err != nil {
return err
}
tree, err = tree.Tree(pkg.Subpath)
if err != nil {
return err
}
return tree.Files().ForEach(func(f *object.File) error {
contents, err := f.Contents()
if err != nil {
return err
}
return c.AddString(contents, "")
})
}