func New(db *database.DB, mailer mailer.Mailer, log *logrus.Logger, cfg *config.Config) *Server { secureCookieKey, _ := base64.StdEncoding.DecodeString(cfg.SecureCookieKey) cookie := securecookie.New( []byte(cfg.SecretKey), secureCookieKey, ) renderOptions := render.Options{ IsDevelopment: cfg.IsDev(), } renderer := render.New(renderOptions) feedparser := feedparser.New() return &Server{ DB: db, Config: cfg, Log: log, Render: renderer, Cookie: cookie, Feedparser: feedparser, Mailer: mailer, } }
// reads the configuration file from the path specified by // the config command line flag. func readConfig(configFile string) error { b, err := ioutil.ReadFile(configFile) if err != nil { return fmt.Errorf("%s config file doesn't exist. Read readme.md for config instructions", configFile) } err = json.Unmarshal(b, &config) if err != nil { return err } cookieAuthKey, err = hex.DecodeString(*config.CookieAuthKeyHexStr) if err != nil { return err } cookieEncrKey, err = hex.DecodeString(*config.CookieEncrKeyHexStr) if err != nil { return err } secureCookie = securecookie.New(cookieAuthKey, cookieEncrKey) // verify auth/encr keys are correct val := map[string]string{ "foo": "bar", } _, err = secureCookie.Encode(cookieName, val) if err != nil { // for convenience, if the auth/encr keys are not set, // generate valid, random value for them fmt.Printf("CookieAuthKeyHexStr and CookieEncrKeyHexStr are invalid or missing in %q\nYou can use the following random values:\n", configFile) auth := securecookie.GenerateRandomKey(32) encr := securecookie.GenerateRandomKey(32) fmt.Printf("CookieAuthKeyHexStr: %s\nCookieEncrKeyHexStr: %s\n", hex.EncodeToString(auth), hex.EncodeToString(encr)) } // TODO: somehow verify twitter creds return err }
// InitFromMetadataOrJSON must be called before any other login methods. // // InitFromMetadataOrJSON will eventually replace all instances of Init, at // which point it will be renamed back to Init(). // // The function first tries to load the cookie salt, client id, and client // secret from GCE project level metadata. If that fails it looks for a // "client_secret.json" file in the current directory to extract the client id // and client secret from. If both of those fail then it returns an error. // // The authWhiteList is the space separated list of domains and email addresses // that are allowed to log in. The authWhiteList will be overwritten from // GCE instance level metadata if present. func InitFromMetadataOrJSON(redirectURL, scopes string, authWhiteList string) error { cookieSalt, clientID, clientSecret := tryLoadingFromMetadata() if clientID == "" { b, err := ioutil.ReadFile("client_secret.json") if err != nil { return fmt.Errorf("Failed to read from metadata and from client_secret.json file: %s", err) } config, err := google.ConfigFromJSON(b) if err != nil { return fmt.Errorf("Failed to read from metadata and decode client_secret.json file: %s", err) } clientID = config.ClientID clientSecret = config.ClientSecret } secureCookie = securecookie.New([]byte(cookieSalt), nil) oauthConfig.ClientId = clientID oauthConfig.ClientSecret = clientSecret oauthConfig.RedirectURL = redirectURL oauthConfig.Scope = scopes // We allow for meta data to not be present. whiteList, err := metadata.Get(metadata.AUTH_WHITE_LIST) if err != nil { glog.Infof("Failed to retrieve auth whitelist from instance meta data: %s", err) } else { authWhiteList = whiteList } activeDomainWhiteList, activeEmailWhiteList = splitAuthWhiteList(authWhiteList) return nil }
// AuthHandler allows to get admin web interface token. func (app *Application) AuthHandler(w http.ResponseWriter, r *http.Request) { password := r.FormValue("password") if app.config.WebPassword == "" || app.config.WebSecret == "" { logger.ERROR.Println("web_password and web_secret must be set in configuration") http.Error(w, "Bad Request", http.StatusBadRequest) return } if password == app.config.WebPassword { w.Header().Set("Content-Type", "application/json") app.RLock() s := securecookie.New([]byte(app.config.WebSecret), nil) app.RUnlock() token, err := s.Encode(AuthTokenKey, AuthTokenValue) if err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } resp := map[string]string{ "token": token, } json.NewEncoder(w).Encode(resp) return } http.Error(w, "Bad Request", http.StatusBadRequest) }
func (a *App) Parse(filepath string) { var ( hashkey []byte blockkey []byte ) file, err := ioutil.ReadFile(filepath) if err != nil { log.Fatal("Could not parse config.json: ", err) } if err := json.Unmarshal(file, a); err != nil { log.Fatal("Error parsing config.json: ", err) } if a.Hashkey == "" { hashkey = securecookie.GenerateRandomKey(16) } else { hashkey = []byte(a.Hashkey) } if a.Blockkey == "" { blockkey = securecookie.GenerateRandomKey(16) } else { blockkey = []byte(a.Blockkey) } a.Scook = securecookie.New(hashkey, blockkey) a.Templates = template.Must(template.ParseGlob("./static/views/*")) }
func NewServer(name string, middlewares ...echo.Middleware) (s *Server) { s = &Server{ Name: name, Apps: make(map[string]*App), apps: make(map[string]*App), DefaultMiddlewares: []echo.Middleware{webxHeader(), mw.Log(), mw.Recover()}, TemplateDir: `template`, Url: `/`, MaxUploadSize: 10 * 1024 * 1024, CookiePrefix: "webx_" + name + "_", CookieHttpOnly: true, } s.InitContext = func(e *echo.Echo) interface{} { return NewContext(s, echo.NewContext(nil, nil, e)) } s.CookieAuthKey = string(codec.GenerateRandomKey(32)) s.CookieBlockKey = string(codec.GenerateRandomKey(32)) s.SessionStoreEngine = `cookie` s.SessionStoreConfig = s.CookieAuthKey s.Codec = codec.New([]byte(s.CookieAuthKey), []byte(s.CookieBlockKey)) s.Core = echo.NewWithContext(s.InitContext) s.URL = NewURL(name, s) s.Core.Use(s.DefaultMiddlewares...) s.Core.Use(middlewares...) servs.Set(name, s) return }
// reads the configuration file from the path specified by // the config command line flag. func readConfig(configFile string) error { b, err := ioutil.ReadFile(configFile) if err != nil { return err } err = json.Unmarshal(b, &config) if err != nil { return err } cookieAuthKey, err = hex.DecodeString(*config.CookieAuthKeyHexStr) if err != nil { return err } cookieEncrKey, err = hex.DecodeString(*config.CookieEncrKeyHexStr) if err != nil { return err } secureCookie = securecookie.New(cookieAuthKey, cookieEncrKey) // verify auth/encr keys are correct val := map[string]string{ "foo": "bar", } _, err = secureCookie.Encode(cookieName, val) if err != nil { // for convenience, if the auth/encr keys are not set, // generate valid, random value for them auth := securecookie.GenerateRandomKey(32) encr := securecookie.GenerateRandomKey(32) fmt.Printf("auth: %s\nencr: %s\n", hex.EncodeToString(auth), hex.EncodeToString(encr)) } // TODO: somehow verify twitter creds return err }
// handles the login process // the first param is a map of strings that will be added to the cookie data before encryption and will be // able to be recovered when Check() is called func Login(ctx *gin.Context, extra map[string]string) error { data := make(map[string]string) for key, value := range extra { if key == "ip" || key == "hash" || key == "experation" { return errors.New("The key '" + key + "' is reserved.") } data[key] = value } // our current time + our expiration time, converted to a unix time stamp data["expiration"] = strconv.FormatInt(time.Now().Add(time.Duration(Expiration)*time.Second).Unix(), 10) data["ip"] = ip(ctx) data["hash"] = hashHeader(ctx) // encode our cookie data securely SecureCookie = securecookie.New(HashKey, BlockKey) if encoded, err := SecureCookie.Encode(CookieName, data); err == nil { //set our cookie cookie := http.Cookie{Name: CookieName, Value: encoded, Path: "/", MaxAge: int(Expiration)} http.SetCookie(ctx.Writer, &cookie) } else { return err } return nil }
func generateCookie() *securecookie.SecureCookie { // Generates SecureCookie type object and returns a pointer to it. // It is used to Encode/Decode plain data to/from a cookie. S := securecookie.New([]byte(config.Config.Secret1), []byte(config.Config.Secret2)) return S }
func NewRouter(db DataHandler) *mux.Router { fe := FrontEnd{DataHandler: db} fe.CookieHandler = securecookie.New(securecookie.GenerateRandomKey(64), securecookie.GenerateRandomKey(32)) fe.CacheOld = true var routes = Routes{ Route{"Index", "GET", "/", Index}, Route{"EventNews", "GET", "/eventnews", EventNewsPage}, Route{"Media", "GET", "/media", MediaPage}, Route{"ExhibitsPage", "GET", "/exhibits", ExhibitsPage}, Route{"Resources", "GET", "/resourcesqq", Resources}, Route{"InfoPage", "GET", "/info", InfoPage}, Route{"GetPosts", "GET", "/get_posts", fe.GetPosts}, Route{"ShowPost", "GET", "/post/{id}", fe.ShowPost}, Route{"ImgUpload", "POST", "/upload_img", ImgUpload}, Route{"AddPost", "POST", "/new_post", fe.NewPost}, Route{"UpdatePost", "POST", "/update_post", fe.UpdatePost}, Route{"DeletePost", "POST", "/delete_postqq/{id}", fe.DeletePost}, } router := mux.NewRouter().StrictSlash(true) for _, route := range routes { router.Methods(route.Method).Path(route.Pattern).Name(route.Name).Handler(route.HandlerFunc) } router.PathPrefix("/").Handler(http.FileServer(http.Dir("./www/"))) return router }
func init() { //configs = my_local.Load_config(filepath.Join(getCurrentDir(), "config.json")) configs = my_config.Load_config("./config.json") //cookieHandler = securecookie.New( // securecookie.GenerateRandomKey(32), // securecookie.GenerateRandomKey(32)) cookieHandler = securecookie.New( []byte(configs.HashKey), []byte(configs.BlockKey)) CSRF = csrf.Protect([]byte(configs.CsrfAuthKey), csrf.Secure(false)) // First we create a FuncMap with which to register the function. funcMap = template.FuncMap{ // The name "title" is what the function will be called in the template text. "trim": strings.TrimSpace, "lower": strings.ToLower, "upper": strings.ToUpper, "safehtml": func(text string) template.HTML { return template.HTML(text) }, } g_templates = make(myTemplates) loadTemplates("") fmt.Printf("%v\n", g_templates) r = gin.New() }
func main() { log.Println("Starting Server") log.Println("Starting mongo db session") session, err := mgo.Dial("localhost") if err != nil { panic(err) } defer session.Close() // Optional. Switch the session to a monotonic behavior. session.SetMode(mgo.Monotonic, true) finalFormsCollection = session.DB("irsForms").C("finalForms") draftFormsCollection = session.DB("irsForms").C("draftForms") userCollection = session.DB("irsForms").C("users") hashKey = []byte(securecookie.GenerateRandomKey(32)) blockKey = []byte(securecookie.GenerateRandomKey(32)) secureCookieInstance = securecookie.New(hashKey, blockKey) r := mux.NewRouter() r.HandleFunc("/register", RegisterHandler) r.HandleFunc("/sockets", SocketsHandler) r.HandleFunc("/links", getLinksHandler).Methods("GET") r.HandleFunc("/updateLinks", UpdateLinksHandler).Methods("POST") r.HandleFunc("/draft_forms", DraftFormsHandler).Methods("GET") r.HandleFunc("/update_draft_forms", UpdateDraftFormsHandler).Methods("POST") r.HandleFunc("/form_report_items", createFormReportHandler).Methods("GET") r.HandleFunc("/draft_form_report_items", createDraftFormReportHandler).Methods("GET") r.PathPrefix("/").Handler(http.FileServer(http.Dir("./public/"))) http.Handle("/", r) log.Println("Listening on 8080") http.ListenAndServe(":8080", nil) }
// checkAuthToken checks admin connection token which Centrifugo returns after admin login func (app *Application) checkAuthToken(token string) error { app.RLock() secret := app.config.WebSecret app.RUnlock() if secret == "" { logger.ERROR.Println("provide web_secret in configuration") return ErrUnauthorized } if token == "" { return ErrUnauthorized } s := securecookie.New([]byte(secret), nil) var val string err := s.Decode(AuthTokenKey, token, &val) if err != nil { return ErrUnauthorized } if val != AuthTokenValue { return ErrUnauthorized } return nil }
func init() { log.SetFlags(log.Lshortfile) hashKey = []byte(os.Getenv("HASHKEY")) if bKey := os.Getenv("BLOCKKEY"); bKey != "" { blockKey = []byte(bKey) } sCookie = securecookie.New(hashKey, blockKey) }
func InitServer(r *mux.Router) { s := &Server{securecookie.New([]byte("MiaMySuperSecret"), []byte("MiaMySuperSecret"))} r.HandleFunc("/send", s.secure(s.handleSend)) r.HandleFunc("/login", s.handleLogin) }
func NewUserCookieCodec(hashKey string, blockKey string) *securecookie.SecureCookie { return securecookie.New( []byte(hashKey), []byte(blockKey), ). SetSerializer(securecookie.JSONEncoder{}). HashFunc(sha512.New) }
// Sign the specified cookie's value func signCookie(ck *http.Cookie, secret string) error { sck := securecookie.New([]byte(secret), nil) enc, err := sck.Encode(ck.Name, ck.Value) if err != nil { return err } ck.Value = enc return nil }
// DecodeState decodes the oauth2 transfer state encoded with EncodeState. func (p Provider) DecodeState(data string) (map[string]string, error) { sc := securecookie.New(p.Secret, p.BlockSecret) sc.MaxAge(int(p.StateLifetime)) state := make(map[string]string) err := sc.Decode(p.SessionKey, data, &state) return state, err }
// Parse a signed cookie and return the cookie value func parseSignedCookie(ck *http.Cookie, secret string) (string, error) { var val string sck := securecookie.New([]byte(secret), nil) err := sck.Decode(ck.Name, ck.Value, &val) if err != nil { return "", err } return val, nil }
// Protect is HTTP middleware that provides Cross-Site Request Forgery // protection. // // It securely generates a masked (unique-per-request) token that // can be embedded in the HTTP response (e.g. form field or HTTP header). // The original (unmasked) token is stored in the session, which is inaccessible // by an attacker (provided you are using HTTPS). Subsequent requests are // expected to include this token, which is compared against the session token. // Requests that do not provide a matching token are served with a HTTP 403 // 'Forbidden' error response. // // Example: // package main // // import ( // "github.com/goji/csrf" // "github.com/zenazn/goji" // ) // // func main() { // // Add the middleware to your router. // goji.Use(csrf.Protect([]byte("32-byte-long-auth-key"))) // goji.Get("/signup", GetSignupForm) // // POST requests without a valid token will return a HTTP 403 Forbidden. // goji.Post("/signup/post", PostSignupForm) // // goji.Serve() // } // // func GetSignupForm(c web.C, w http.ResponseWriter, r *http.Request) { // // signup_form.tmpl just needs a {{ .csrfField }} template tag for // // csrf.TemplateField to inject the CSRF token into. Easy! // t.ExecuteTemplate(w, "signup_form.tmpl", map[string]interface{ // csrf.TemplateTag: csrf.TemplateField(c, r), // }) // // We could also retrieve the token directly from csrf.Token(c, r) and // // set it in the request header - w.Header.Set("X-CSRF-Token", token) // // This is useful if your sending JSON to clients or a front-end JavaScript // // framework. // } // func Protect(authKey []byte, opts ...Option) func(*web.C, http.Handler) http.Handler { return func(c *web.C, h http.Handler) http.Handler { cs := parseOptions(h, opts...) // Set the defaults if no options have been specified if cs.opts.ErrorHandler == nil { cs.opts.ErrorHandler = web.HandlerFunc(unauthorizedHandler) } if cs.opts.MaxAge < 1 { // Default of 12 hours cs.opts.MaxAge = 3600 * 12 } if cs.opts.FieldName == "" { cs.opts.FieldName = fieldName } if cs.opts.CookieName == "" { cs.opts.CookieName = cookieName } if cs.opts.RequestHeader == "" { cs.opts.RequestHeader = headerName } // Create an authenticated securecookie instance. if cs.sc == nil { cs.sc = securecookie.New(authKey, nil) // Use JSON serialization (faster than one-off gob encoding) cs.sc.SetSerializer(securecookie.JSONEncoder{}) // Set the MaxAge of the underlying securecookie. cs.sc.MaxAge(cs.opts.MaxAge) } if cs.st == nil { // Default to the cookieStore cs.st = &cookieStore{ name: cs.opts.CookieName, maxAge: cs.opts.MaxAge, secure: cs.opts.Secure, httpOnly: cs.opts.HttpOnly, path: cs.opts.Path, domain: cs.opts.Domain, sc: cs.sc, } } // Initialize Goji's request context cs.c = c return *cs } }
func encodeBadState(p *Provider, state map[string]string, t *testing.T) string { sc := securecookie.New([]byte(p.Secret), []byte(p.BlockSecret)) sc.MaxAge(int(p.StateLifetime)) s, err := sc.Encode(p.SessionKey, state) if err != nil { t.Error("encodeBadState should not error") } return s }
func (c *Context) GetAuthInfo(r *http.Request) (*UserData, error) { if c.cookieCodec == nil { c.cookieCodec = securecookie.New(c.SecureKey, nil) } var uid int64 if cookie, err := r.Cookie("uid"); err == nil { if err = c.cookieCodec.Decode("uid", cookie.Value, &uid); err == nil { return c.GetUserFull(uid) } } return nil, ErrUserNotExist }
func createCookie() *http.Cookie { hashKey := securecookie.GenerateRandomKey(32) s := securecookie.New(hashKey, blockKey) sessionID, _ := uuid.NewV4() log.Println("UUID: ", sessionID) encoded, _ := s.Encode("sessionID", sessionID) cookie := &http.Cookie{ Name: "sessionID", Value: encoded, } return cookie }
func Write(w http.ResponseWriter, c *Cookie) { s := securecookie.New(HashKey, BlockKey) if encoded, err := s.Encode(c.Name, c.Values); err == nil { cookie := &http.Cookie{ Name: c.Name, Value: encoded, Path: c.Path, } http.SetCookie(w, cookie) } }
// EncodeState returns an encoded (and secure) oauth2 transfer state for the // provided session id, named provider, and specified resource. func (p Provider) EncodeState(sessionID, provName, resource string) (string, error) { sc := securecookie.New(p.Secret, p.BlockSecret) sc.MaxAge(int(p.StateLifetime)) state := map[string]string{ "sid": sessionID, "provider": provName, "resource": resource, } return sc.Encode(p.SessionKey, state) }
func newAuthWithKeys(db db.DB, cookieKey []byte, passwordSalt []byte) *Auth { if len(cookieKey) != 64 { panic("Cookie key should be 64 bytes long") } a := &Auth{ db: db, passwordSalt: passwordSalt, secureCookie: securecookie.New(cookieKey, nil), } a.PingHandler = a.RequireUser(http.HandlerFunc(a.pingHandler)) return a }
func init() { // Register the custom type to gob. gob.Register(new(authToken)) bitmonster.OnInit(func() { // Create a new secure cookie object with the cookie keys secureCookie = securecookie.New([]byte(settings.Settings.AuthHashKey), []byte(settings.Settings.AuthBlockKey)) // Set the max age in seconds secureCookie.MaxAge(settings.Settings.AuthSessionMaxAge) }) }
func NewTickets(sessionSecret, encryptionSecret []byte, realm string) Tickets { tickets := &tickets{ nil, realm, fmt.Sprintf("token@%s", realm), encryptionSecret, } tickets.SecureCookie = securecookie.New(sessionSecret, encryptionSecret) tickets.MaxAge(86400 * 30) // 30 days tickets.HashFunc(sha256.New) tickets.BlockFunc(aes.NewCipher) return tickets }
func NewSecureCookie(hmacKey []byte, optionalEncryptionKey []byte) (sc *SecureCookie, err error) { if hmacKey == nil { return nil, errors.New("requires hmac key") } var ec []byte = nil if optionalEncryptionKey != nil && len(optionalEncryptionKey) > 0 { ec = optionalEncryptionKey } return &SecureCookie{ hmacKey: hmacKey, encryptKey: ec, secureCookie: securecookie.New(hmacKey, ec)}, nil }
func Read(r *http.Request, name string) (*Cookie, error) { s := securecookie.New(HashKey, BlockKey) cookie, err := r.Cookie(name) if err != nil { return nil, err } values := CookieValues{} err = s.Decode(name, cookie.Value, &values) if err != nil { return nil, err } return &Cookie{Name: cookie.Name, Path: cookie.Path, Values: values}, nil }