github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/authentication/agent.go (about) 1 // Copyright 2014 Canonical Ltd. All rights reserved. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package authentication 5 6 import ( 7 "context" 8 9 "github.com/juju/errors" 10 11 apiservererrors "github.com/juju/juju/apiserver/errors" 12 "github.com/juju/juju/state" 13 ) 14 15 // EntityAuthenticator performs authentication for juju entities. 16 type AgentAuthenticator struct{} 17 18 var _ EntityAuthenticator = (*AgentAuthenticator)(nil) 19 20 type taggedAuthenticator interface { 21 state.Entity 22 state.Authenticator 23 } 24 25 // Authenticate authenticates the provided entity. 26 // It takes an entityfinder and the tag used to find the entity that requires authentication. 27 func (*AgentAuthenticator) Authenticate(ctx context.Context, entityFinder EntityFinder, authParams AuthParams) (state.Entity, error) { 28 entity, err := entityFinder.FindEntity(authParams.AuthTag) 29 if errors.Is(err, errors.NotFound) { 30 logger.Debugf("cannot authenticate unknown entity: %v", authParams.AuthTag) 31 return nil, errors.Trace(apiservererrors.ErrBadCreds) 32 } 33 if err != nil { 34 return nil, errors.Trace(err) 35 } 36 authenticator, ok := entity.(taggedAuthenticator) 37 if !ok { 38 return nil, errors.Trace(apiservererrors.ErrBadRequest) 39 } 40 if !authenticator.PasswordValid(authParams.Credentials) { 41 return nil, errors.Trace(apiservererrors.ErrBadCreds) 42 } 43 44 // If this is a machine agent connecting, we need to check the 45 // nonce matches, otherwise the wrong agent might be trying to 46 // connect. 47 // 48 // NOTE(axw) with the current implementation of Login, it is 49 // important that we check the password before checking the 50 // nonce, or an unprovisioned machine in a hosted model will 51 // prevent a controller machine from logging into the hosted 52 // model. 53 if machine, ok := authenticator.(*state.Machine); ok { 54 if !machine.CheckProvisioned(authParams.Nonce) { 55 return nil, errors.NotProvisionedf("machine %v", machine.Id()) 56 } 57 } 58 59 return entity, nil 60 }