diff --git a/parse.go b/parse.go new file mode 100644 index 0000000..5d9d7f8 --- /dev/null +++ b/parse.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "github.com/KatolaZ/git2go" + "golang.org/x/crypto/openpgp" + "os" + "strings" + "log" +) + +func CommitToString(commit *git.Commit) string { + + var ret string + + ret += fmt.Sprintf("type: %s\n", commit.Type()) + ret += fmt.Sprintf("Id: %s\n", commit.Id()) + ret += fmt.Sprintf("Author: %s\n", commit.Author()) + ret += fmt.Sprintf("Message: %s\n", commit.Message()) + ret += fmt.Sprintf("Parent-count: %d\n", commit.ParentCount()) + + return ret +} + +// FIXME: RETURN THE ENTITY PROVIDED BY THE CHECK, OR nil +func check_signature(commit *git.Commit, keyring *openpgp.KeyRing) (signature, signed string, err error) { + + signature, signed, err = commit.ExtractSignature() + if err == nil { + + _, err_sig := + openpgp.CheckArmoredDetachedSignature(*keyring, strings.NewReader(signed), + strings.NewReader(signature)) + + if err_sig == nil { + fmt.Printf("Good signature \n") + return signature, signed, nil + } + err = err_sig + } + + return "", "", err +} + +func walk_commits(msg SCORSHmsg, keyring openpgp.KeyRing) int { + + fmt.Printf("Inside parse_commits\n") + + reponame := msg.repo + old_rev := msg.old_rev + new_rev := msg.new_rev + + repo, err := git.OpenRepository(reponame) + if err != nil { + fmt.Fprintf(os.Stderr, "Error while opening repository %s (%s)\n", + reponame, err) + return SCORSH_ERR_NO_REPO + } + + old_rev_oid, err := git.NewOid(old_rev) + + oldrev_commit, err := repo.LookupCommit(old_rev_oid) + if err != nil { + fmt.Fprintf(os.Stderr, "Commit: %s does not exist\n", old_rev) + return SCORSH_ERR_NO_COMMIT + } + + new_rev_oid, err := git.NewOid(new_rev) + + newrev_commit, err := repo.LookupCommit(new_rev_oid) + if err != nil { + fmt.Fprintf(os.Stderr, "Commit: %s does not exist\n", new_rev) + return SCORSH_ERR_NO_COMMIT + } + + cur_commit := newrev_commit + + for cur_commit.Id().String() != oldrev_commit.Id().String() { + + commit, err := repo.LookupCommit(cur_commit.Id()) + if err == nil { + + fmt.Printf("%s", CommitToString(commit)) + //signature, signed, err := check_signature(commit, &keyring) + _, _, err := check_signature(commit, &keyring) + if err != nil { + log.Printf("%s\n", SCORSHErr(SCORSH_ERR_SIGNATURE)) + + } + cur_commit = commit.Parent(0) + } else { + fmt.Printf("Commit %x not found!\n", cur_commit.Id()) + return SCORSH_ERR_NO_COMMIT + } + } + return 0 +} diff --git a/scorsh.go b/scorsh.go new file mode 100644 index 0000000..cf8e5f0 --- /dev/null +++ b/scorsh.go @@ -0,0 +1,81 @@ +package main + +import ( + "errors" + "golang.org/x/crypto/openpgp" + "log" + "os" +) + +const ( + SCORSH_ERR_NO_FILE = -(1 << iota) + SCORSH_ERR_KEYRING + SCORSH_ERR_NO_REPO + SCORSH_ERR_NO_COMMIT + SCORSH_ERR_SIGNATURE +) + +type SCORSHmsg struct { + repo string + branch string + old_rev string + new_rev string +} + +func SCORSHErr(err int) error { + + var err_str string + + switch err { + case SCORSH_ERR_NO_FILE: + err_str = "Invalid file name" + case SCORSH_ERR_KEYRING: + err_str = "Invalid keyring" + case SCORSH_ERR_NO_REPO: + err_str = "Invalid repository" + case SCORSH_ERR_NO_COMMIT: + err_str = "Invalid commit ID" + case SCORSH_ERR_SIGNATURE: + err_str = "Invalid signature" + default: + err_str = "Generic Error" + } + + return errors.New(err_str) + +} + +func SCORSHWorker(keyring string, c_msg chan SCORSHmsg, c_status chan int) { + + // read the worker configuration file + + // Open the keyring file + f, err := os.Open(keyring) + defer f.Close() + + if err != nil { + log.Printf("[worker] cannot open file %s\n", keyring) + c_status <- SCORSH_ERR_NO_FILE + return + } + + // load the keyring + kr, err := openpgp.ReadArmoredKeyRing(f) + + if err != nil { + log.Printf("[worker] cannot open keyring %s\n", keyring) + log.Printf("%s\n", err) + c_status <- SCORSH_ERR_KEYRING + return + } + + // wait for messages from the c_msg channel + + msg := <-c_msg + + // process message + ret := walk_commits(msg, kr) + + c_status <- ret + +} diff --git a/spooler.go b/spooler.go new file mode 100644 index 0000000..c0bc8a1 --- /dev/null +++ b/spooler.go @@ -0,0 +1,44 @@ +package main + +import ( + "github.com/fsnotify/fsnotify" + "log" + "os" +) + +// parse a request file and return a SCORSHmessage +func parse_request(fname string) (SCORSHmsg, error) { + + var ret SCORSHmsg + _, err := os.Open(fname) + if err != nil { + log.Printf("Unable to open file: %s\n", fname) + return ret, SCORSHErr(SCORSH_ERR_NO_FILE) + } + + return ret, nil + +} + +func spooler(watcher *fsnotify.Watcher, worker chan SCORSHmsg) { + + for { + select { + case event := <-watcher.Events: + if event.Op == fsnotify.Create { + msg, err := parse_request(event.Name) + if err != nil { + log.Printf("Invalid packet received. [%s]\n", err) + } + worker <- msg + } + case err := <-watcher.Errors: + log.Println("error:", err) + } + } +} + + +func main(){ + +}