package main import ( "bufio" "crypto/md5" "fmt" "log" "os" "os/exec" "strings" ) // printf "USER:PASS" | base64 | while read a; do printf "%s" "$a" | md5sum; done const AuthFilename = "/home/neale/.config/g.cgi/authorization" const GitProjectRoot = "/home/neale/projects" 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 } // Build up a string to match 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) authfile, err := os.Open(AuthFilename) if err != nil { log.Fatal(err) } defer authfile.Close() scanner := bufio.NewScanner(authfile) for scanner.Scan() { line := scanner.Text() if line == "" || strings.HasPrefix(line, "#") { continue; } if line == hashhex { os.Setenv("AUTH_TYPE", parts[0]) os.Setenv("REMOTE_USER", "XXX-neale") return true } } return false } func notice() { fmt.Println("Content-type: text/html") fmt.Println() fmt.Println("") fmt.Println("") fmt.Println("Neale's Projects have Moved") fmt.Println("") fmt.Println("") fmt.Println("

Neale's Projects have Moved

") fmt.Println("I've moved most of my stuff to") fmt.Println("Github.") fmt.Println("

") fmt.Println("X11 things may now be in the") fmt.Println("9wm team.") fmt.Println("

") fmt.Println("Network security things may now be in the") fmt.Println("dirtbags team.") fmt.Println("") } func main() { log.SetFlags(0) //log.SetOutput(os.Stdout) //log.SetPrefix("Status: 500 CGI Go Boom\nContent-type: text/plain\n\nERROR: ") uri := os.Getenv("REQUEST_URI") switch { case strings.HasSuffix(uri, "git-upload-pack") || strings.HasSuffix(uri, "git-receive-pack"): if Authenticated() { os.Setenv("GIT_PROJECT_ROOT", GitProjectRoot) 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")) } default: notice() } }