diff options
| -rw-r--r-- | parse.go | 97 | ||||
| -rw-r--r-- | scorsh.go | 81 | ||||
| -rw-r--r-- | spooler.go | 44 | 
3 files changed, 222 insertions, 0 deletions
| 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(){ + +} | 
