// initSignatureV4 initializing signature verification func initSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) { // strip auth from authorization header authHeaderValue := req.Header.Get("Authorization") accessKeyID, err := stripAccessKeyID(authHeaderValue) if err != nil { return nil, err.Trace() } authConfig, err := auth.LoadConfig() if err != nil { return nil, err.Trace() } authFields := strings.Split(strings.TrimSpace(authHeaderValue), ",") signedHeaders := strings.Split(strings.Split(strings.TrimSpace(authFields[1]), "=")[1], ";") signature := strings.Split(strings.TrimSpace(authFields[2]), "=")[1] for _, user := range authConfig.Users { if user.AccessKeyID == accessKeyID { signature := &donut.Signature{ AccessKeyID: user.AccessKeyID, SecretAccessKey: user.SecretAccessKey, Signature: signature, SignedHeaders: signedHeaders, Request: req, } return signature, nil } } return nil, probe.NewError(errors.New("AccessKeyID not found")) }
// resetAuth reset auth keys for a user func resetAuth(args *AuthArgs, reply *AuthRep) *probe.Error { config, err := auth.LoadConfig() if err != nil { return err.Trace() } if _, ok := config.Users[args.User]; !ok { return probe.NewError(errors.New("User not found")) } accessKeyID, err := auth.GenerateAccessKeyID() if err != nil { return err.Trace() } reply.AccessKeyID = string(accessKeyID) secretAccessKey, err := auth.GenerateSecretAccessKey() if err != nil { return err.Trace() } reply.SecretAccessKey = string(secretAccessKey) reply.Name = args.User config.Users[args.User] = &auth.User{ Name: args.User, AccessKeyID: string(accessKeyID), SecretAccessKey: string(secretAccessKey), } return auth.SaveConfig(config).Trace() }
// initPresignedSignatureV4 initializing presigned signature verification func initPresignedSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) { credentialElements := strings.Split(strings.TrimSpace(req.URL.Query().Get("X-Amz-Credential")), "/") if len(credentialElements) != 5 { return nil, probe.NewError(errCredentialTagMalformed) } accessKeyID := credentialElements[0] if !auth.IsValidAccessKey(accessKeyID) { return nil, probe.NewError(errAccessKeyIDInvalid) } authConfig, err := auth.LoadConfig() if err != nil { return nil, err.Trace() } signedHeaders := strings.Split(strings.TrimSpace(req.URL.Query().Get("X-Amz-SignedHeaders")), ";") signature := strings.TrimSpace(req.URL.Query().Get("X-Amz-Signature")) for _, user := range authConfig.Users { if user.AccessKeyID == accessKeyID { signature := &donut.Signature{ AccessKeyID: user.AccessKeyID, SecretAccessKey: user.SecretAccessKey, Signature: signature, SignedHeaders: signedHeaders, Presigned: true, Request: req, } return signature, nil } } return nil, probe.NewError(errAccessKeyIDInvalid) }
// validate auth header handler ServeHTTP() wrapper func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { acceptsContentType := getContentType(r) accessKeyID, err := stripAccessKeyID(r.Header.Get("Authorization")) switch err.ToGoError() { case errInvalidRegion: writeErrorResponse(w, r, AuthorizationHeaderMalformed, acceptsContentType, r.URL.Path) return case errAccessKeyIDInvalid: writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path) return case nil: // load auth config authConfig, err := auth.LoadConfig() if err != nil { writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) return } // Access key not found for _, user := range authConfig.Users { if user.AccessKeyID == accessKeyID { h.handler.ServeHTTP(w, r) return } } writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path) return // All other errors for now, serve them default: // control reaches here, we should just send the request up the stack - internally // individual calls will validate themselves against un-authenticated requests h.handler.ServeHTTP(w, r) } }
// InitSignatureV4 initializing signature verification func InitSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) { // strip auth from authorization header ah := req.Header.Get("Authorization") var accessKeyID string { var err error accessKeyID, err = StripAccessKeyID(ah) if err != nil { return nil, probe.NewError(err) } } authConfig, err := auth.LoadConfig() if err != nil { return nil, err.Trace() } if _, ok := authConfig.Users[accessKeyID]; !ok { return nil, probe.NewError(errors.New("AccessID not found")) } signature := &donut.Signature{ AccessKeyID: authConfig.Users[accessKeyID].AccessKeyID, SecretAccessKey: authConfig.Users[accessKeyID].SecretAccessKey, AuthHeader: ah, Request: req, } return signature, nil }
// fetchAuth fetch auth keys for a user func fetchAuth(args *AuthArgs, reply *AuthRep) *probe.Error { config, err := auth.LoadConfig() if err != nil { return err.Trace() } if _, ok := config.Users[args.User]; !ok { return probe.NewError(errors.New("User not found")) } reply.AccessKeyID = config.Users[args.User].AccessKeyID reply.SecretAccessKey = config.Users[args.User].SecretAccessKey reply.Name = args.User return nil }
// InitSignatureV4 initializing signature verification func InitSignatureV4(req *http.Request) (*donut.Signature, error) { // strip auth from authorization header ah := req.Header.Get("Authorization") accessKeyID, err := StripAccessKeyID(ah) if err != nil { return nil, iodine.New(err, nil) } authConfig, err := auth.LoadConfig() if _, ok := authConfig.Users[accessKeyID]; !ok { return nil, errors.New("Access ID not found") } signature := &donut.Signature{ AccessKeyID: authConfig.Users[accessKeyID].AccessKeyID, SecretAccessKey: authConfig.Users[accessKeyID].SecretAccessKey, AuthHeader: ah, Request: req, } return signature, nil }
// generateAuth generate new auth keys for a user func generateAuth(args *AuthArgs, reply *AuthRep) *probe.Error { config, err := auth.LoadConfig() if err != nil { if os.IsNotExist(err.ToGoError()) { // Initialize new config, since config file doesn't exist yet config = &auth.Config{} config.Version = "0.0.1" config.Users = make(map[string]*auth.User) } else { return err.Trace() } } if _, ok := config.Users[args.User]; ok { return probe.NewError(errors.New("Credentials already set, if you wish to change this invoke Reset() method")) } accessKeyID, err := auth.GenerateAccessKeyID() if err != nil { return err.Trace() } reply.AccessKeyID = string(accessKeyID) secretAccessKey, err := auth.GenerateSecretAccessKey() if err != nil { return err.Trace() } reply.SecretAccessKey = string(secretAccessKey) reply.Name = args.User config.Users[args.User] = &auth.User{ Name: args.User, AccessKeyID: string(accessKeyID), SecretAccessKey: string(secretAccessKey), } if err := auth.SaveConfig(config); err != nil { return err.Trace() } return nil }
// validate auth header handler ServeHTTP() wrapper func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { acceptsContentType := getContentType(r) accessKeyID, err := StripAccessKeyID(r.Header.Get("Authorization")) switch err.(type) { case nil: // load auth config authConfig, err := auth.LoadConfig() if err != nil { writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) return } // Access key not found if _, ok := authConfig.Users[accessKeyID]; !ok { writeErrorResponse(w, r, InvalidAccessKeyID, acceptsContentType, r.URL.Path) return } h.handler.ServeHTTP(w, r) default: // control reaches here, we should just send the request up the stack - internally // individual calls will validate themselves against un-authenticated requests h.handler.ServeHTTP(w, r) } }
// validate auth header handler ServeHTTP() wrapper func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { acceptsContentType := getContentType(r) ah, err := stripAuth(r) switch err.(type) { case nil: authConfig, err := auth.LoadConfig() if err != nil { writeErrorResponse(w, r, InternalError, acceptsContentType, r.URL.Path) return } _, ok := authConfig.Users[ah.accessKey] if !ok { writeErrorResponse(w, r, AccessDenied, acceptsContentType, r.URL.Path) return } // Success h.handler.ServeHTTP(w, r) default: // control reaches here, we should just send the request up the stack - internally // individual calls will validate themselves against un-authenticated requests h.handler.ServeHTTP(w, r) } }
// initSignatureV4 initializing signature verification func initSignatureV4(req *http.Request) (*donut.Signature, *probe.Error) { // strip auth from authorization header authHeaderValue := req.Header.Get("Authorization") accessKeyID, err := stripAccessKeyID(authHeaderValue) if err != nil { return nil, err.Trace() } authConfig, err := auth.LoadConfig() if err != nil { return nil, err.Trace() } for _, user := range authConfig.Users { if user.AccessKeyID == accessKeyID { signature := &donut.Signature{ AccessKeyID: user.AccessKeyID, SecretAccessKey: user.SecretAccessKey, AuthHeader: authHeaderValue, Request: req, } return signature, nil } } return nil, probe.NewError(errors.New("AccessKeyID not found")) }