// newCSRF initializes a new CSRF handler func newCSRFHandler(keyPath string) func(h http.Handler) http.Handler { authKey := newAuthKey(keyPath) return csrf.Protect( authKey, csrf.HttpOnly(false), csrf.Secure(false), ) }
func createHandler(dir string, d string, e string, flags TLSFlags) http.Handler { var ( mux = http.NewServeMux() fileHandler = http.FileServer(http.Dir(dir)) h http.Handler ) u, perr := url.Parse(e) if perr != nil { log.Fatal(perr) } if u.Scheme == "tcp" { if flags.tls { h = createTcpHandlerWithTLS(u, flags) } else { h = createTcpHandler(u) } } else if u.Scheme == "unix" { var socketPath = u.Path if _, err := os.Stat(socketPath); err != nil { if os.IsNotExist(err) { log.Fatalf("unix socket %s does not exist", socketPath) } log.Fatal(err) } h = createUnixHandler(socketPath) } else { log.Fatalf("Bad Docker enpoint: %s. Only unix:// and tcp:// are supported.", e) } // Use existing csrf authKey if present or generate a new one. var authKeyPath = d + "/" + authKeyFile dat, err := ioutil.ReadFile(authKeyPath) if err != nil { fmt.Println(err) authKey = securecookie.GenerateRandomKey(32) err := ioutil.WriteFile(authKeyPath, authKey, 0644) if err != nil { fmt.Println("unable to persist auth key", err) } } else { authKey = dat } CSRF := csrf.Protect( authKey, csrf.HttpOnly(false), csrf.Secure(false), ) mux.Handle("/dockerapi/", http.StripPrefix("/dockerapi", h)) mux.Handle("/", fileHandler) return CSRF(csrfWrapper(mux)) }
// ServeSSL serves cosgo on port 443 with attached key+cert func (c *Cosgo) ServeSSL() { go func() { time.Sleep(100 * time.Millisecond) log.Println("Cosgo: Serving TLS on", *sslport) }() log.Fatalln(http.ListenAndServeTLS(*sslport, *path2cert, *path2key, csrf.Protect(c.antiCSRFkey, csrf.HttpOnly(true), csrf.FieldName(*cookie), csrf.CookieName(*cookie), csrf.Secure(true), csrf.MaxAge(600), csrf.ErrorHandler(http.HandlerFunc(csrfErrorHandler)), )(c.r))) }
func main() { // Create the server, load mbox and fortunes and run initialize cosgo := setup() // Set all the needed /url paths e := cosgo.route(cwd) if e != nil { log.Fatalln(e) } // Needs to be compiled with build tag 'debug' to be redefined, and -debug CLI flag to be activated if *debug { cosgo.debug() } cosgo.Bind = *bind cosgo.Port = strconv.Itoa(*portnum) log.Println("Refreshing every", *refreshTime) go func() { time.Sleep(100 * time.Millisecond) log.Println("Listening on", cosgo.Bind+":"+cosgo.Port) }() // Try to bind listener, binderr := net.Listen("tcp", cosgo.Bind+":"+cosgo.Port) if binderr != nil { log.Println(binderr) os.Exit(1) } if cosgo.antiCSRFkey == nil { cosgo.antiCSRFkey = anticsrfGen() } if *path2cert != *path2key { go cosgo.ServeSSL() } // Is nolog enabled? if *nolog { *logfile = os.DevNull } // stdout or a filename openLogFile() // Start Serving // Here we either use fastcgi or normal http server, using csrf and mux. // with custom csrf error handler and 10 minute cookie. if !*fastcgi { go func() { if listener != nil { go http.Serve(listener, csrf.Protect(cosgo.antiCSRFkey, csrf.HttpOnly(true), csrf.FieldName(*cookie), csrf.CookieName(*cookie), csrf.Secure(*secure), csrf.MaxAge(600), csrf.ErrorHandler(http.HandlerFunc(csrfErrorHandler)))(cosgo.r)) } else { log.Fatalln("nil listener") } }() } else { go func() { if listener != nil { go fcgi.Serve(listener, csrf.Protect(cosgo.antiCSRFkey, csrf.HttpOnly(true), csrf.FieldName(*cookie), csrf.CookieName(*cookie), csrf.Secure(*secure), csrf.MaxAge(600), csrf.ErrorHandler(http.HandlerFunc(csrfErrorHandler)))(cosgo.r)) } else { log.Fatalln("nil listener") } }() } select { // Fire up the cosgo engine case <-time.After(*refreshTime): cosgo.rw.Lock() if *debug && !*quiet { log.Println("Info: Generating Random 40 URL Key...") } t1 := time.Now() // set a random URL key (40 char length). kee := generateURLKey(40) cosgo.URLKey = kee if *debug && !*quiet { log.Printf("Generated URL Key %q in %v", cosgo.URLKey, time.Now().Sub(t1)) } cosgo.rw.Unlock() // every X minutes change the URL key (default 42 minutes) // break tests uncomment next line //*refreshTime = time.Nanosecond if !*quiet { log.Printf("Uptime: %s (%s)", time.Since(timeboot), humanize(time.Since(timeboot))) log.Printf("Hits: %v", hitcounter) log.Printf("Messages: %v", inboxcount) if *debug { log.Printf("Port: %v", cosgo.Port) } if *path2cert != "" { log.Println("TLS: ON") } } } }