github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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 "github.com/juju/errors" 8 "gopkg.in/juju/names.v2" 9 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/apiserver/params" 12 "github.com/juju/juju/state" 13 ) 14 15 // AgentIdentityProvider performs authentication for machine and unit agents. 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(entityFinder EntityFinder, tag names.Tag, req params.LoginRequest) (state.Entity, error) { 28 entity, err := entityFinder.FindEntity(tag) 29 if errors.IsNotFound(err) { 30 return nil, errors.Trace(common.ErrBadCreds) 31 } 32 if err != nil { 33 return nil, errors.Trace(err) 34 } 35 authenticator, ok := entity.(taggedAuthenticator) 36 if !ok { 37 return nil, errors.Trace(common.ErrBadRequest) 38 } 39 if !authenticator.PasswordValid(req.Credentials) { 40 return nil, errors.Trace(common.ErrBadCreds) 41 } 42 43 // If this is a machine agent connecting, we need to check the 44 // nonce matches, otherwise the wrong agent might be trying to 45 // connect. 46 // 47 // NOTE(axw) with the current implementation of Login, it is 48 // important that we check the password before checking the 49 // nonce, or an unprovisioned machine in a hosted model will 50 // prevent a controller machine from logging into the hosted 51 // model. 52 if machine, ok := authenticator.(*state.Machine); ok { 53 if !machine.CheckProvisioned(req.Nonce) { 54 return nil, errors.NotProvisionedf("machine %v", machine.Id()) 55 } 56 } 57 58 return entity, nil 59 }