diff --git a/Makefile b/Makefile index 2ac14e4..a6dfae7 100644 --- a/Makefile +++ b/Makefile @@ -48,8 +48,8 @@ $(DESTDIR)/geneweb.cgi: geneweb.c $(CC) -o $@ $< chmod +s $@ -$(DESTDIR)/g.cgi: g.cgi.c - $(CC) -o $@ $< +$(DESTDIR)/g.cgi: g.cgi.go + go build -o $@ $< $(DESTDIR)/mp.cgi: minepig.cgi.go go build -o $@ $< diff --git a/cgitrc b/cgitrc index 0082908..bf5b6d5 100644 --- a/cgitrc +++ b/cgitrc @@ -1,6 +1,7 @@ strict-export=git-daemon-export-ok about-filter=/home/neale/public_html/about-filter.sh +readme=:README.mdwn readme=:README section-from-path=1 diff --git a/g.cgi.c b/g.cgi.c deleted file mode 100644 index 089964b..0000000 --- a/g.cgi.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -#define GIT_PROJECT_ROOT "/home/neale/projects" -#define CGIT_CONFIG "/home/neale/public_html/cgitrc" -#define CGIT "/usr/lib/cgit/cgit.cgi" - -int -main(int argc, char *argv[]) -{ - char *uri = getenv("REQUEST_URI"); - - if (uri && strstr(uri, "git-upload-pack")) { - /* Use git-http-backend for great speed! */ - setenv("GIT_PROJECT_ROOT", GIT_PROJECT_ROOT, 1); - execlp("git", "git", "http-backend", NULL); - } else { - setenv("CGIT_CONFIG", CGIT_CONFIG, 1); - execl(CGIT, "cgit", NULL); - } - - return 0; -} diff --git a/g.cgi.go b/g.cgi.go new file mode 100644 index 0000000..bbf671c --- /dev/null +++ b/g.cgi.go @@ -0,0 +1,84 @@ +package main + +import ( + "crypto/md5" + "fmt" + "log" + "os" + "os/exec" + "strings" +) + +const GitProjectRoot = "/home/neale/projects" +const CgitConfig = "/home/neale/public_html/cgitrc" +const Cgit = "/usr/lib/cgit/cgit.cgi" + +// printf "USER:PASS" | base64 | while read a; do printf "%s" "$a" | md5sum; done +var allowed = []string{ + "2c64993e88c06e297d4f01cf3b5aebdf", // neale +} + +func execv(name string, arg ...string) { + c := exec.Command(name, arg...) + c.Stdin = os.Stdin + c.Stdout = os.Stdout + c.Stderr = os.Stderr + if err := c.Run(); err != nil { + log.Print(err) + } +} + +func Authenticated() bool { + auth := os.Getenv("HTTP_AUTHORIZATION") + if auth == "" { + return false + } + + parts := strings.Split(auth, " ") + switch { + case len(parts) != 2: + return false + case parts[0] != "Basic": + return false + } + + hash := md5.Sum([]byte(parts[1])) + hashhex := fmt.Sprintf("%x", hash) + + for _, a := range allowed { + if a == hashhex { + os.Setenv("AUTH_TYPE", parts[0]) + os.Setenv("REMOTE_USER", "XXX-neale") + return true + } + } + + return false +} + +func main() { + log.SetFlags(0) + //log.SetOutput(os.Stdout) + //log.SetPrefix("Status: 500 CGI Go Boom\nContent-type: text/plain\n\nERROR: ") + + os.Setenv("GIT_PROJECT_ROOT", GitProjectRoot) + os.Setenv("CGIT_CONFIG", CgitConfig) + + uri := os.Getenv("REQUEST_URI") + switch { + case strings.HasSuffix(uri, "git-receive-pack"): + if Authenticated() { + execv("git", "http-backend") + } else { + fmt.Println("Status: 401 Not Authorized") + fmt.Println("Content-type: text/plain") + fmt.Println("WWW-Authenticate: Basic realm=\"git\"") + fmt.Println() + fmt.Println("Nope", os.Getenv("HTTP_AUTHORIZATION")) + } + case strings.HasSuffix(uri, "git-upload-pack"): + execv("git", "http-backend") + default: + execv(Cgit) + } +}