Ejemplo n.º 1
0
// Authorized simply checks for the existence of the authorization header,
// responding with a bearer challenge if it doesn't exist.
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	req, err := ctxu.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	if req.Header.Get("Authorization") == "" {
		challenge := challenge{
			realm:   ac.realm,
			service: ac.service,
		}

		if len(accessRecords) > 0 {
			var scopes []string
			for _, access := range accessRecords {
				scopes = append(scopes, fmt.Sprintf("%s:%s:%s", access.Type, access.Resource.Name, access.Action))
			}
			challenge.scope = strings.Join(scopes, " ")
		}

		return nil, &challenge
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: "silly"}), nil
}
Ejemplo n.º 2
0
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	req, err := context.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	username, password, ok := req.BasicAuth()
	if !ok {
		return nil, &challenge{
			realm: ac.realm,
			err:   auth.ErrInvalidCredential,
		}
	}

	// Dynamically parsing the latest account list
	fstat, err := os.Stat(ac.path)
	if err != nil {
		return nil, err
	}

	lastModified := fstat.ModTime()
	ac.mu.Lock()
	if ac.htpasswd == nil || !ac.modtime.Equal(lastModified) {
		ac.modtime = lastModified

		f, err := os.Open(ac.path)
		if err != nil {
			ac.mu.Unlock()
			return nil, err
		}
		defer f.Close()

		h, err := newHTPasswd(f)
		if err != nil {
			ac.mu.Unlock()
			return nil, err
		}
		ac.htpasswd = h
	}
	localHTPasswd := ac.htpasswd
	ac.mu.Unlock()

	if err := localHTPasswd.authenticateUser(username, password); err != nil {
		context.GetLogger(ctx).Errorf("error authenticating user %q: %v", username, err)
		return nil, &challenge{
			realm: ac.realm,
			err:   auth.ErrAuthenticationFailure,
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: username}), nil
}
Ejemplo n.º 3
0
// Authorized handles checking whether the given request is authorized
// for actions on resources described by the given access items.
func (ac *accessController) Authorized(ctx context.Context, accessItems ...auth.Access) (context.Context, error) {
	challenge := &authChallenge{
		realm:     ac.realm,
		service:   ac.service,
		accessSet: newAccessSet(accessItems...),
	}

	req, err := context.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	parts := strings.Split(req.Header.Get("Authorization"), " ")

	if len(parts) != 2 || strings.ToLower(parts[0]) != "bearer" {
		challenge.err = ErrTokenRequired
		return nil, challenge
	}

	rawToken := parts[1]

	token, err := NewToken(rawToken)
	if err != nil {
		challenge.err = err
		return nil, challenge
	}

	verifyOpts := VerifyOptions{
		TrustedIssuers:    []string{ac.issuer},
		AcceptedAudiences: []string{ac.service},
		Roots:             ac.rootCerts,
		TrustedKeys:       ac.trustedKeys,
	}

	if err = token.Verify(verifyOpts); err != nil {
		challenge.err = err
		return nil, challenge
	}

	accessSet := token.accessSet()
	for _, access := range accessItems {
		if !accessSet.contains(access) {
			challenge.err = ErrInsufficientScope
			return nil, challenge
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: token.Claims.Subject}), nil
}
Ejemplo n.º 4
0
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	req, err := ctxu.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	username, password, ok := req.BasicAuth()
	if !ok {
		return nil, &challenge{
			realm: ac.realm,
			err:   ErrInvalidCredential,
		}
	}

	if err := ac.htpasswd.authenticateUser(username, password); err != nil {
		ctxu.GetLogger(ctx).Errorf("error authenticating user %q: %v", username, err)
		return nil, &challenge{
			realm: ac.realm,
			err:   ErrAuthenticationFailure,
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: username}), nil
}
Ejemplo n.º 5
0
// Authorized simply checks for the existence of the SSL CLIENT headers,
// using which entitlement check is done
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	var resData ResponseData
	var err1 error
	req, err := context.GetRequest(ctx)
	//res, err2 := context.GetResponseWriter(ctx)
	if err != nil {
		return nil, err
	}

	if req.Header.Get("SSL_CLIENT_CERT") == "" {
		log.Debugln("repo name: %s", getName(ctx))

		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	pemStr := req.Header.Get("SSL_CLIENT_CERT")
	log.Debugln("SSL CERT: %s", pemStr)
	repoName := getName(ctx)
	//if it is a push request
	//or the the URI requested is /v2/ (ping)
	//then don't call authentication service
	log.Debugln("requestURI: ", req.RequestURI)
	log.Debugln("requested repo name: ", getName(ctx))
	if skipAuth(req) {
		log.Debugln("Returning without calling authentication servie")
		return auth.WithUser(ctx, auth.UserInfo{Name: "entitled-ping"}), nil
	}

	// check for repo name being empty. If repo name is empty
	// and the URI is not for ping, return authentication error
	if "/v2/" != req.RequestURI && repoName == "" {
		log.Errorln("No repo name retrieved. This should not happen")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure as no repo name has been supplied"),
		}
	}

	libraryName := repoName[:strings.LastIndex(repoName, "/")+1]
	log.Debugln("Computed library name: ", libraryName)
	path := fmt.Sprintf("/content/dist/rhel/server/7/7Server/x86_64/containers/registry/%s", libraryName)

	if resData, err1 = ac.service.CheckEntitlementV2(req, path); err1 != nil {
		log.Errorln("Service returned error: ", err1)
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	if resData.Verified != "true" {
		log.Errorln("Service returned unauthenticated/unauthorized")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: "entitled"}), nil
}