github.com/Aestek/consul@v1.2.4-0.20190309222502-b2c31e33971a/agent/consul/acl.go (about)

     1  package consul
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"sync"
     8  	"time"
     9  
    10  	"github.com/armon/go-metrics"
    11  	"github.com/hashicorp/consul/acl"
    12  	"github.com/hashicorp/consul/agent/structs"
    13  	"github.com/hashicorp/consul/api"
    14  	"github.com/hashicorp/consul/sentinel"
    15  	"golang.org/x/time/rate"
    16  )
    17  
    18  // These must be kept in sync with the constants in command/agent/acl.go.
    19  const (
    20  	// anonymousToken is the token ID we re-write to if there is no token ID
    21  	// provided.
    22  	anonymousToken = "anonymous"
    23  
    24  	// redactedToken is shown in structures with embedded tokens when they
    25  	// are not allowed to be displayed.
    26  	redactedToken = "<hidden>"
    27  
    28  	// aclUpgradeBatchSize controls how many tokens we look at during each round of upgrading. Individual raft logs
    29  	// will be further capped using the aclBatchUpsertSize. This limit just prevents us from creating a single slice
    30  	// with all tokens in it.
    31  	aclUpgradeBatchSize = 128
    32  
    33  	// aclUpgradeRateLimit is the number of batch upgrade requests per second.
    34  	aclUpgradeRateLimit rate.Limit = 1.0
    35  
    36  	// aclBatchDeleteSize is the number of deletions to send in a single batch operation. 4096 should produce a batch that is <150KB
    37  	// in size but should be sufficiently large to handle 1 replication round in a single batch
    38  	aclBatchDeleteSize = 4096
    39  
    40  	// aclBatchUpsertSize is the target size in bytes we want to submit for a batch upsert request. We estimate the size at runtime
    41  	// due to the data being more variable in its size.
    42  	aclBatchUpsertSize = 256 * 1024
    43  
    44  	// DEPRECATED (ACL-Legacy-Compat) aclModeCheck* are all only for legacy usage
    45  	// aclModeCheckMinInterval is the minimum amount of time between checking if the
    46  	// agent should be using the new or legacy ACL system. All the places it is
    47  	// currently used will backoff as it detects that it is remaining in legacy mode.
    48  	// However the initial min value is kept small so that new cluster creation
    49  	// can enter into new ACL mode quickly.
    50  	aclModeCheckMinInterval = 50 * time.Millisecond
    51  
    52  	// aclModeCheckMaxInterval controls the maximum interval for how often the agent
    53  	// checks if it should be using the new or legacy ACL system.
    54  	aclModeCheckMaxInterval = 30 * time.Second
    55  
    56  	// Maximum number of re-resolution requests to be made if the token is modified between
    57  	// resolving the token and resolving its policies that would remove one of its policies.
    58  	tokenPolicyResolutionMaxRetries = 5
    59  )
    60  
    61  func minTTL(a time.Duration, b time.Duration) time.Duration {
    62  	if a < b {
    63  		return a
    64  	}
    65  	return b
    66  }
    67  
    68  type ACLRemoteError struct {
    69  	Err error
    70  }
    71  
    72  func (e ACLRemoteError) Error() string {
    73  	return fmt.Sprintf("Error communicating with the ACL Datacenter: %v", e.Err)
    74  }
    75  
    76  func IsACLRemoteError(err error) bool {
    77  	_, ok := err.(ACLRemoteError)
    78  	return ok
    79  }
    80  
    81  type ACLResolverDelegate interface {
    82  	ACLsEnabled() bool
    83  	ACLDatacenter(legacy bool) string
    84  	// UseLegacyACLs
    85  	UseLegacyACLs() bool
    86  	ResolveIdentityFromToken(token string) (bool, structs.ACLIdentity, error)
    87  	ResolvePolicyFromID(policyID string) (bool, *structs.ACLPolicy, error)
    88  	RPC(method string, args interface{}, reply interface{}) error
    89  }
    90  
    91  type remoteACLLegacyResult struct {
    92  	authorizer acl.Authorizer
    93  	err        error
    94  }
    95  
    96  type remoteACLIdentityResult struct {
    97  	identity structs.ACLIdentity
    98  	err      error
    99  }
   100  
   101  type remoteACLPolicyResult struct {
   102  	policy *structs.ACLPolicy
   103  	err    error
   104  }
   105  
   106  type policyTokenError struct {
   107  	Err   error
   108  	token string
   109  }
   110  
   111  func (e policyTokenError) Error() string {
   112  	return e.Err.Error()
   113  }
   114  
   115  // ACLResolverConfig holds all the configuration necessary to create an ACLResolver
   116  type ACLResolverConfig struct {
   117  	Config *Config
   118  	Logger *log.Logger
   119  
   120  	// CacheConfig is a pass through configuration for ACL cache limits
   121  	CacheConfig *structs.ACLCachesConfig
   122  
   123  	// Delegate that implements some helper functionality that is server/client specific
   124  	Delegate ACLResolverDelegate
   125  
   126  	// AutoDisable indicates that RPC responses should be checked and if they indicate ACLs are disabled
   127  	// remotely then disable them locally as well. This is particularly useful for the client agent
   128  	// so that it can detect when the servers have gotten ACLs enabled.
   129  	AutoDisable bool
   130  
   131  	Sentinel sentinel.Evaluator
   132  }
   133  
   134  // ACLResolver is the type to handle all your token and policy resolution needs.
   135  //
   136  // Supports:
   137  //   - Resolving tokens locally via the ACLResolverDelegate
   138  //   - Resolving policies locally via the ACLResolverDelegate
   139  //   - Resolving legacy tokens remotely via a ACL.GetPolicy RPC
   140  //   - Resolving tokens remotely via an ACL.TokenRead RPC
   141  //   - Resolving policies remotely via an ACL.PolicyResolve RPC
   142  //
   143  // Remote Resolution:
   144  //   Remote resolution can be done syncrhonously or asynchronously depending
   145  //   on the ACLDownPolicy in the Config passed to the resolver.
   146  //
   147  //   When the down policy is set to async-cache and we have already cached values
   148  //   then go routines will be spawned to perform the RPCs in the background
   149  //   and then will udpate the cache with either the positive or negative result.
   150  //
   151  //   When the down policy is set to extend-cache or the token/policy is not already
   152  //   cached then the same go routines are spawned to do the RPCs in the background.
   153  //   However in this mode channels are created to receive the results of the RPC
   154  //   and are registered with the resolver. Those channels are immediately read/blocked
   155  //   upon.
   156  //
   157  type ACLResolver struct {
   158  	config *Config
   159  	logger *log.Logger
   160  
   161  	delegate ACLResolverDelegate
   162  	sentinel sentinel.Evaluator
   163  
   164  	cache                     *structs.ACLCaches
   165  	asyncIdentityResults      map[string][]chan (*remoteACLIdentityResult)
   166  	asyncIdentityResultsMutex sync.RWMutex
   167  	asyncPolicyResults        map[string][]chan (*remoteACLPolicyResult)
   168  	asyncPolicyResultsMutex   sync.RWMutex
   169  	asyncLegacyResults        map[string][]chan (*remoteACLLegacyResult)
   170  	asyncLegacyMutex          sync.RWMutex
   171  
   172  	down acl.Authorizer
   173  
   174  	autoDisable  bool
   175  	disabled     time.Time
   176  	disabledLock sync.RWMutex
   177  }
   178  
   179  func NewACLResolver(config *ACLResolverConfig) (*ACLResolver, error) {
   180  	if config == nil {
   181  		return nil, fmt.Errorf("ACL Resolver must be initialized with a config")
   182  	}
   183  
   184  	if config.Config == nil {
   185  		return nil, fmt.Errorf("ACLResolverConfig.Config must not be nil")
   186  	}
   187  
   188  	if config.Delegate == nil {
   189  		return nil, fmt.Errorf("ACL Resolver must be initialized with a valid delegate")
   190  	}
   191  
   192  	if config.Logger == nil {
   193  		config.Logger = log.New(os.Stderr, "", log.LstdFlags)
   194  	}
   195  
   196  	cache, err := structs.NewACLCaches(config.CacheConfig)
   197  	if err != nil {
   198  		return nil, err
   199  	}
   200  
   201  	var down acl.Authorizer
   202  	switch config.Config.ACLDownPolicy {
   203  	case "allow":
   204  		down = acl.AllowAll()
   205  	case "deny":
   206  		down = acl.DenyAll()
   207  	case "async-cache", "extend-cache":
   208  		// Leave the down policy as nil to signal this.
   209  	default:
   210  		return nil, fmt.Errorf("invalid ACL down policy %q", config.Config.ACLDownPolicy)
   211  	}
   212  
   213  	return &ACLResolver{
   214  		config:               config.Config,
   215  		logger:               config.Logger,
   216  		delegate:             config.Delegate,
   217  		sentinel:             config.Sentinel,
   218  		cache:                cache,
   219  		asyncIdentityResults: make(map[string][]chan (*remoteACLIdentityResult)),
   220  		asyncPolicyResults:   make(map[string][]chan (*remoteACLPolicyResult)),
   221  		asyncLegacyResults:   make(map[string][]chan (*remoteACLLegacyResult)),
   222  		autoDisable:          config.AutoDisable,
   223  		down:                 down,
   224  	}, nil
   225  }
   226  
   227  // fireAsyncLegacyResult is used to notify any watchers that legacy resolution of a token is complete
   228  func (r *ACLResolver) fireAsyncLegacyResult(token string, authorizer acl.Authorizer, ttl time.Duration, err error) {
   229  	// cache the result: positive or negative
   230  	r.cache.PutAuthorizerWithTTL(token, authorizer, ttl)
   231  
   232  	// get the list of channels to send the result to
   233  	r.asyncLegacyMutex.Lock()
   234  	channels := r.asyncLegacyResults[token]
   235  	delete(r.asyncLegacyResults, token)
   236  	r.asyncLegacyMutex.Unlock()
   237  
   238  	// notify all watchers of the RPC results
   239  	result := &remoteACLLegacyResult{authorizer, err}
   240  	for _, cx := range channels {
   241  		// only chans that are being blocked on will be in the list of channels so this cannot block
   242  		cx <- result
   243  		close(cx)
   244  	}
   245  }
   246  
   247  func (r *ACLResolver) resolveTokenLegacyAsync(token string, cached *structs.AuthorizerCacheEntry) {
   248  	req := structs.ACLPolicyResolveLegacyRequest{
   249  		Datacenter: r.delegate.ACLDatacenter(true),
   250  		ACL:        token,
   251  	}
   252  
   253  	cacheTTL := r.config.ACLTokenTTL
   254  	if cached != nil {
   255  		cacheTTL = cached.TTL
   256  	}
   257  
   258  	var reply structs.ACLPolicyResolveLegacyResponse
   259  	err := r.delegate.RPC("ACL.GetPolicy", &req, &reply)
   260  	if err == nil {
   261  		parent := acl.RootAuthorizer(reply.Parent)
   262  		if parent == nil {
   263  			r.fireAsyncLegacyResult(token, cached.Authorizer, cacheTTL, acl.ErrInvalidParent)
   264  			return
   265  		}
   266  
   267  		var policies []*acl.Policy
   268  		policy := reply.Policy
   269  		if policy != nil {
   270  			policies = append(policies, policy.ConvertFromLegacy())
   271  		}
   272  
   273  		authorizer, err := acl.NewPolicyAuthorizer(parent, policies, r.sentinel)
   274  		r.fireAsyncLegacyResult(token, authorizer, reply.TTL, err)
   275  		return
   276  	}
   277  
   278  	if acl.IsErrNotFound(err) {
   279  		// Make sure to remove from the cache if it was deleted
   280  		r.fireAsyncLegacyResult(token, nil, cacheTTL, acl.ErrNotFound)
   281  		return
   282  	}
   283  
   284  	// some other RPC error
   285  	switch r.config.ACLDownPolicy {
   286  	case "allow":
   287  		r.fireAsyncLegacyResult(token, acl.AllowAll(), cacheTTL, nil)
   288  		return
   289  	case "async-cache", "extend-cache":
   290  		if cached != nil {
   291  			r.fireAsyncLegacyResult(token, cached.Authorizer, cacheTTL, nil)
   292  			return
   293  		}
   294  		fallthrough
   295  	default:
   296  		r.fireAsyncLegacyResult(token, acl.DenyAll(), cacheTTL, nil)
   297  		return
   298  	}
   299  }
   300  
   301  func (r *ACLResolver) resolveTokenLegacy(token string) (acl.Authorizer, error) {
   302  	defer metrics.MeasureSince([]string{"acl", "resolveTokenLegacy"}, time.Now())
   303  
   304  	// Attempt to resolve locally first (local results are not cached)
   305  	// This is only useful for servers where either legacy replication is being
   306  	// done or the server is within the primary datacenter.
   307  	if done, identity, err := r.delegate.ResolveIdentityFromToken(token); done {
   308  		if err == nil && identity != nil {
   309  			policies, err := r.resolvePoliciesForIdentity(identity)
   310  			if err != nil {
   311  				return nil, err
   312  			}
   313  
   314  			return policies.Compile(acl.RootAuthorizer(r.config.ACLDefaultPolicy), r.cache, r.sentinel)
   315  		}
   316  
   317  		return nil, err
   318  	}
   319  
   320  	// Look in the cache prior to making a RPC request
   321  	entry := r.cache.GetAuthorizer(token)
   322  
   323  	if entry != nil && entry.Age() <= minTTL(entry.TTL, r.config.ACLTokenTTL) {
   324  		metrics.IncrCounter([]string{"acl", "token", "cache_hit"}, 1)
   325  		if entry.Authorizer != nil {
   326  			return entry.Authorizer, nil
   327  		}
   328  		return nil, acl.ErrNotFound
   329  	}
   330  
   331  	metrics.IncrCounter([]string{"acl", "token", "cache_miss"}, 1)
   332  
   333  	// Resolve the token in the background and wait on the result if we must
   334  	var waitChan chan *remoteACLLegacyResult
   335  	waitForResult := entry == nil || r.config.ACLDownPolicy != "async-cache"
   336  
   337  	r.asyncLegacyMutex.Lock()
   338  
   339  	// check if resolution for this token is already happening
   340  	waiters, ok := r.asyncLegacyResults[token]
   341  	if !ok || waiters == nil {
   342  		// initialize the slice of waiters if not already done
   343  		waiters = make([]chan *remoteACLLegacyResult, 0)
   344  	}
   345  	if waitForResult {
   346  		// create the waitChan only if we are going to block waiting
   347  		// for the response and then append it to the list of waiters
   348  		// Because we will block (not select or discard this chan) we
   349  		// do not need to create it as buffered
   350  		waitChan = make(chan *remoteACLLegacyResult)
   351  		r.asyncLegacyResults[token] = append(waiters, waitChan)
   352  	}
   353  	r.asyncLegacyMutex.Unlock()
   354  
   355  	if !ok {
   356  		// start the async RPC if it wasn't already ongoing
   357  		go r.resolveTokenLegacyAsync(token, entry)
   358  	}
   359  
   360  	if !waitForResult {
   361  		// waitForResult being false requires the cacheEntry to not be nil
   362  		if entry.Authorizer != nil {
   363  			return entry.Authorizer, nil
   364  		}
   365  		return nil, acl.ErrNotFound
   366  	}
   367  
   368  	// block waiting for the async RPC to finish.
   369  	res := <-waitChan
   370  	return res.authorizer, res.err
   371  }
   372  
   373  // fireAsyncTokenResult is used to notify all waiters that the results of a token resolution is complete
   374  func (r *ACLResolver) fireAsyncTokenResult(token string, identity structs.ACLIdentity, err error) {
   375  	// cache the result: positive or negative
   376  	r.cache.PutIdentity(token, identity)
   377  
   378  	// get the list of channels to send the result to
   379  	r.asyncIdentityResultsMutex.Lock()
   380  	channels := r.asyncIdentityResults[token]
   381  	delete(r.asyncIdentityResults, token)
   382  	r.asyncIdentityResultsMutex.Unlock()
   383  
   384  	// notify all watchers of the RPC results
   385  	result := &remoteACLIdentityResult{identity, err}
   386  	for _, cx := range channels {
   387  		// cannot block because all wait chans will have another goroutine blocked on the read
   388  		cx <- result
   389  		close(cx)
   390  	}
   391  }
   392  
   393  func (r *ACLResolver) resolveIdentityFromTokenAsync(token string, cached *structs.IdentityCacheEntry) {
   394  	req := structs.ACLTokenGetRequest{
   395  		Datacenter:  r.delegate.ACLDatacenter(false),
   396  		TokenID:     token,
   397  		TokenIDType: structs.ACLTokenSecret,
   398  		QueryOptions: structs.QueryOptions{
   399  			Token:      token,
   400  			AllowStale: true,
   401  		},
   402  	}
   403  
   404  	var resp structs.ACLTokenResponse
   405  	err := r.delegate.RPC("ACL.TokenRead", &req, &resp)
   406  	if err == nil {
   407  		if resp.Token == nil {
   408  			r.fireAsyncTokenResult(token, nil, acl.ErrNotFound)
   409  		} else {
   410  			r.fireAsyncTokenResult(token, resp.Token, nil)
   411  		}
   412  		return
   413  	}
   414  
   415  	if acl.IsErrNotFound(err) {
   416  		// Make sure to remove from the cache if it was deleted
   417  		r.fireAsyncTokenResult(token, nil, acl.ErrNotFound)
   418  		return
   419  	}
   420  
   421  	// some other RPC error
   422  	if cached != nil && (r.config.ACLDownPolicy == "extend-cache" || r.config.ACLDownPolicy == "async-cache") {
   423  		// extend the cache
   424  		r.fireAsyncTokenResult(token, cached.Identity, nil)
   425  	}
   426  
   427  	r.fireAsyncTokenResult(token, nil, err)
   428  	return
   429  }
   430  
   431  func (r *ACLResolver) resolveIdentityFromToken(token string) (structs.ACLIdentity, error) {
   432  	// Attempt to resolve locally first (local results are not cached)
   433  	if done, identity, err := r.delegate.ResolveIdentityFromToken(token); done {
   434  		return identity, err
   435  	}
   436  
   437  	// Check the cache before making any RPC requests
   438  	cacheEntry := r.cache.GetIdentity(token)
   439  	if cacheEntry != nil && cacheEntry.Age() <= r.config.ACLTokenTTL {
   440  		metrics.IncrCounter([]string{"acl", "token", "cache_hit"}, 1)
   441  		return cacheEntry.Identity, nil
   442  	}
   443  
   444  	metrics.IncrCounter([]string{"acl", "token", "cache_miss"}, 1)
   445  
   446  	// Background a RPC request and wait on it if we must
   447  	var waitChan chan *remoteACLIdentityResult
   448  
   449  	waitForResult := cacheEntry == nil || r.config.ACLDownPolicy != "async-cache"
   450  
   451  	r.asyncIdentityResultsMutex.Lock()
   452  	// check if resolution of this token is already ongoing
   453  	waiters, ok := r.asyncIdentityResults[token]
   454  	if !ok || waiters == nil {
   455  		// only initialize the slice of waiters if need be (when this token resolution isn't ongoing)
   456  		waiters = make([]chan *remoteACLIdentityResult, 0)
   457  	}
   458  	if waitForResult {
   459  		// create the waitChan only if we are going to block waiting
   460  		// for the response and then append it to the list of waiters
   461  		// Because we will block (not select or discard this chan) we
   462  		// do not need to create it as buffered
   463  		waitChan = make(chan *remoteACLIdentityResult)
   464  		r.asyncIdentityResults[token] = append(waiters, waitChan)
   465  	}
   466  	r.asyncIdentityResultsMutex.Unlock()
   467  
   468  	if !ok {
   469  		// only start the RPC if one isn't in flight
   470  		go r.resolveIdentityFromTokenAsync(token, cacheEntry)
   471  	}
   472  
   473  	if !waitForResult {
   474  		// waitForResult being false requires the cacheEntry to not be nil
   475  		return cacheEntry.Identity, nil
   476  	}
   477  
   478  	// block on the read here, this is why we don't need chan buffering
   479  	res := <-waitChan
   480  
   481  	if res.err != nil && !acl.IsErrNotFound(res.err) {
   482  		return res.identity, ACLRemoteError{Err: res.err}
   483  	}
   484  	return res.identity, res.err
   485  }
   486  
   487  // fireAsyncPolicyResult is used to notify all waiters that policy resolution is complete.
   488  func (r *ACLResolver) fireAsyncPolicyResult(policyID string, policy *structs.ACLPolicy, err error, updateCache bool) {
   489  	if updateCache {
   490  		// cache the result: positive or negative
   491  		r.cache.PutPolicy(policyID, policy)
   492  	}
   493  
   494  	// get the list of channels to send the result to
   495  	r.asyncPolicyResultsMutex.Lock()
   496  	channels := r.asyncPolicyResults[policyID]
   497  	delete(r.asyncPolicyResults, policyID)
   498  	r.asyncPolicyResultsMutex.Unlock()
   499  
   500  	// notify all watchers of the RPC results
   501  	result := &remoteACLPolicyResult{policy, err}
   502  	for _, cx := range channels {
   503  		// not closing the channel as there could be more events to be fired.
   504  		cx <- result
   505  	}
   506  }
   507  
   508  func (r *ACLResolver) resolvePoliciesAsyncForIdentity(identity structs.ACLIdentity, policyIDs []string, cached map[string]*structs.PolicyCacheEntry) {
   509  	req := structs.ACLPolicyBatchGetRequest{
   510  		Datacenter: r.delegate.ACLDatacenter(false),
   511  		PolicyIDs:  policyIDs,
   512  		QueryOptions: structs.QueryOptions{
   513  			Token:      identity.SecretToken(),
   514  			AllowStale: true,
   515  		},
   516  	}
   517  
   518  	found := make(map[string]struct{})
   519  	var resp structs.ACLPolicyBatchResponse
   520  	err := r.delegate.RPC("ACL.PolicyResolve", &req, &resp)
   521  	if err == nil {
   522  		for _, policy := range resp.Policies {
   523  			r.fireAsyncPolicyResult(policy.ID, policy, nil, true)
   524  			found[policy.ID] = struct{}{}
   525  		}
   526  
   527  		for _, policyID := range policyIDs {
   528  			if _, ok := found[policyID]; !ok {
   529  				r.fireAsyncPolicyResult(policyID, nil, acl.ErrNotFound, true)
   530  			}
   531  		}
   532  		return
   533  	}
   534  
   535  	if acl.IsErrNotFound(err) {
   536  		// make sure to indicate that this identity is no longer valid within
   537  		// the cache
   538  		//
   539  		// Note - This must be done before firing the results or else it would
   540  		// be possible for waiters to get woken up an get the cached identity
   541  		// again
   542  		r.cache.PutIdentity(identity.SecretToken(), nil)
   543  		for _, policyID := range policyIDs {
   544  			// Do not touch the cache. Getting a top level ACL not found error
   545  			// only indicates that the secret token used in the request
   546  			// no longer exists
   547  			r.fireAsyncPolicyResult(policyID, nil, &policyTokenError{acl.ErrNotFound, identity.SecretToken()}, false)
   548  		}
   549  		return
   550  	}
   551  
   552  	if acl.IsErrPermissionDenied(err) {
   553  		// invalidate our ID cache so that identity resolution will take place
   554  		// again in the future
   555  		//
   556  		// Note - This must be done before firing the results or else it would
   557  		// be possible for waiters to get woken up and get the cached identity
   558  		// again
   559  		r.cache.RemoveIdentity(identity.SecretToken())
   560  
   561  		for _, policyID := range policyIDs {
   562  			// Do not remove from the cache for permission denied
   563  			// what this does indicate is that our view of the token is out of date
   564  			r.fireAsyncPolicyResult(policyID, nil, &policyTokenError{acl.ErrPermissionDenied, identity.SecretToken()}, false)
   565  		}
   566  		return
   567  	}
   568  
   569  	// other RPC error - use cache if available
   570  
   571  	extendCache := r.config.ACLDownPolicy == "extend-cache" || r.config.ACLDownPolicy == "async-cache"
   572  	for _, policyID := range policyIDs {
   573  		if entry, ok := cached[policyID]; extendCache && ok {
   574  			r.fireAsyncPolicyResult(policyID, entry.Policy, nil, true)
   575  		} else {
   576  			r.fireAsyncPolicyResult(policyID, nil, ACLRemoteError{Err: err}, true)
   577  		}
   578  	}
   579  	return
   580  }
   581  
   582  func (r *ACLResolver) filterPoliciesByScope(policies structs.ACLPolicies) structs.ACLPolicies {
   583  	var out structs.ACLPolicies
   584  	for _, policy := range policies {
   585  		if len(policy.Datacenters) == 0 {
   586  			out = append(out, policy)
   587  			continue
   588  		}
   589  
   590  		for _, dc := range policy.Datacenters {
   591  			if dc == r.config.Datacenter {
   592  				out = append(out, policy)
   593  				continue
   594  			}
   595  		}
   596  	}
   597  
   598  	return out
   599  }
   600  
   601  func (r *ACLResolver) resolvePoliciesForIdentity(identity structs.ACLIdentity) (structs.ACLPolicies, error) {
   602  	policyIDs := identity.PolicyIDs()
   603  	if len(policyIDs) == 0 {
   604  		policy := identity.EmbeddedPolicy()
   605  		if policy != nil {
   606  			return []*structs.ACLPolicy{policy}, nil
   607  		}
   608  
   609  		// In this case the default policy will be all that is in effect.
   610  		return nil, nil
   611  	}
   612  
   613  	// For the new ACLs policy replication is mandatory for correct operation on servers. Therefore
   614  	// we only attempt to resolve policies locally
   615  	policies := make([]*structs.ACLPolicy, 0, len(policyIDs))
   616  
   617  	// Get all associated policies
   618  	var missing []string
   619  	var expired []*structs.ACLPolicy
   620  	expCacheMap := make(map[string]*structs.PolicyCacheEntry)
   621  
   622  	for _, policyID := range policyIDs {
   623  		if done, policy, err := r.delegate.ResolvePolicyFromID(policyID); done {
   624  			if err != nil && !acl.IsErrNotFound(err) {
   625  				return nil, err
   626  			}
   627  
   628  			if policy != nil {
   629  				policies = append(policies, policy)
   630  			} else {
   631  				r.logger.Printf("[WARN] acl: policy %q not found for identity %q", policyID, identity.ID())
   632  			}
   633  
   634  			continue
   635  		}
   636  
   637  		// create the missing list which we can execute an RPC to get all the missing policies at once
   638  		entry := r.cache.GetPolicy(policyID)
   639  		if entry == nil {
   640  			missing = append(missing, policyID)
   641  			continue
   642  		}
   643  
   644  		if entry.Policy == nil {
   645  			// this happens when we cache a negative response for the policies existence
   646  			continue
   647  		}
   648  
   649  		if entry.Age() >= r.config.ACLPolicyTTL {
   650  			expired = append(expired, entry.Policy)
   651  			expCacheMap[policyID] = entry
   652  		} else {
   653  			policies = append(policies, entry.Policy)
   654  		}
   655  	}
   656  
   657  	// Hot-path if we have no missing or expired policies
   658  	if len(missing)+len(expired) == 0 {
   659  		return r.filterPoliciesByScope(policies), nil
   660  	}
   661  
   662  	fetchIDs := missing
   663  	for _, policy := range expired {
   664  		fetchIDs = append(fetchIDs, policy.ID)
   665  	}
   666  
   667  	// Background a RPC request and wait on it if we must
   668  	var waitChan chan *remoteACLPolicyResult
   669  	waitForResult := len(missing) > 0 || r.config.ACLDownPolicy != "async-cache"
   670  	if waitForResult {
   671  		// buffered because there are going to be multiple go routines that send data to this chan
   672  		waitChan = make(chan *remoteACLPolicyResult, len(fetchIDs))
   673  	}
   674  
   675  	var newAsyncFetchIds []string
   676  	r.asyncPolicyResultsMutex.Lock()
   677  	for _, policyID := range fetchIDs {
   678  		clients, ok := r.asyncPolicyResults[policyID]
   679  		if !ok || clients == nil {
   680  			clients = make([]chan *remoteACLPolicyResult, 0)
   681  		}
   682  		if waitForResult {
   683  			r.asyncPolicyResults[policyID] = append(clients, waitChan)
   684  		}
   685  
   686  		if !ok {
   687  			newAsyncFetchIds = append(newAsyncFetchIds, policyID)
   688  		}
   689  	}
   690  	r.asyncPolicyResultsMutex.Unlock()
   691  
   692  	if len(newAsyncFetchIds) > 0 {
   693  		// only start the RPC if one isn't in flight
   694  		go r.resolvePoliciesAsyncForIdentity(identity, newAsyncFetchIds, expCacheMap)
   695  	}
   696  
   697  	if !waitForResult {
   698  		// waitForResult being false requires that all the policies were cached already
   699  		policies = append(policies, expired...)
   700  		return r.filterPoliciesByScope(policies), nil
   701  	}
   702  
   703  	for i := 0; i < len(fetchIDs); i++ {
   704  		res := <-waitChan
   705  
   706  		if res.err != nil {
   707  			if _, ok := res.err.(*policyTokenError); ok {
   708  				// always return token errors
   709  				return nil, res.err
   710  			} else if !acl.IsErrNotFound(res.err) {
   711  				// ignore regular not found errors for policies
   712  				return nil, res.err
   713  			}
   714  		}
   715  
   716  		// we probably could handle a special case where we
   717  		// get a permission denied error due to another requests
   718  		// issues and spawn the go routine to resolve it ourselves.
   719  		// however this should be exceedingly rare and in this case
   720  		// we can just kick the can down the road and retry the whole
   721  		// token/policy resolution. All the remaining good bits that
   722  		// we need will already be cached anyways.
   723  
   724  		if res.policy != nil {
   725  			policies = append(policies, res.policy)
   726  		}
   727  	}
   728  
   729  	return r.filterPoliciesByScope(policies), nil
   730  }
   731  
   732  func (r *ACLResolver) resolveTokenToPolicies(token string) (structs.ACLPolicies, error) {
   733  	_, policies, err := r.resolveTokenToIdentityAndPolicies(token)
   734  	return policies, err
   735  }
   736  
   737  func (r *ACLResolver) resolveTokenToIdentityAndPolicies(token string) (structs.ACLIdentity, structs.ACLPolicies, error) {
   738  	var lastErr error
   739  	var lastIdentity structs.ACLIdentity
   740  
   741  	for i := 0; i < tokenPolicyResolutionMaxRetries; i++ {
   742  		// Resolve the token to an ACLIdentity
   743  		identity, err := r.resolveIdentityFromToken(token)
   744  		if err != nil {
   745  			return nil, nil, err
   746  		} else if identity == nil {
   747  			return nil, nil, acl.ErrNotFound
   748  		}
   749  
   750  		lastIdentity = identity
   751  
   752  		policies, err := r.resolvePoliciesForIdentity(identity)
   753  		if err == nil {
   754  			return identity, policies, nil
   755  		}
   756  		lastErr = err
   757  
   758  		if tokenErr, ok := err.(*policyTokenError); ok {
   759  			if acl.IsErrNotFound(err) && tokenErr.token == identity.SecretToken() {
   760  				// token was deleted while resolving policies
   761  				return nil, nil, acl.ErrNotFound
   762  			}
   763  
   764  			// other types of policyTokenErrors should cause retrying the whole token
   765  			// resolution process
   766  		} else {
   767  			return identity, nil, err
   768  		}
   769  	}
   770  
   771  	return lastIdentity, nil, lastErr
   772  }
   773  
   774  func (r *ACLResolver) disableACLsWhenUpstreamDisabled(err error) error {
   775  	if !r.autoDisable || err == nil || !acl.IsErrDisabled(err) {
   776  		return err
   777  	}
   778  
   779  	r.logger.Printf("[DEBUG] acl: ACLs disabled on upstream servers, will check again after %s", r.config.ACLDisabledTTL)
   780  	r.disabledLock.Lock()
   781  	r.disabled = time.Now().Add(r.config.ACLDisabledTTL)
   782  	r.disabledLock.Unlock()
   783  
   784  	return err
   785  }
   786  
   787  func (r *ACLResolver) ResolveToken(token string) (acl.Authorizer, error) {
   788  	if !r.ACLsEnabled() {
   789  		return nil, nil
   790  	}
   791  
   792  	if acl.RootAuthorizer(token) != nil {
   793  		return nil, acl.ErrRootDenied
   794  	}
   795  
   796  	// handle the anonymous token
   797  	if token == "" {
   798  		token = anonymousToken
   799  	}
   800  
   801  	if r.delegate.UseLegacyACLs() {
   802  		authorizer, err := r.resolveTokenLegacy(token)
   803  		return authorizer, r.disableACLsWhenUpstreamDisabled(err)
   804  	}
   805  
   806  	defer metrics.MeasureSince([]string{"acl", "ResolveToken"}, time.Now())
   807  
   808  	policies, err := r.resolveTokenToPolicies(token)
   809  	if err != nil {
   810  		r.disableACLsWhenUpstreamDisabled(err)
   811  		if IsACLRemoteError(err) {
   812  			r.logger.Printf("[ERR] consul.acl: %v", err)
   813  			return r.down, nil
   814  		}
   815  
   816  		return nil, err
   817  	}
   818  
   819  	// Build the Authorizer
   820  	authorizer, err := policies.Compile(acl.RootAuthorizer(r.config.ACLDefaultPolicy), r.cache, r.sentinel)
   821  	return authorizer, err
   822  
   823  }
   824  
   825  func (r *ACLResolver) ACLsEnabled() bool {
   826  	// Whether we desire ACLs to be enabled according to configuration
   827  	if !r.delegate.ACLsEnabled() {
   828  		return false
   829  	}
   830  
   831  	if r.autoDisable {
   832  		// Whether ACLs are disabled according to RPCs failing with a ACLs Disabled error
   833  		r.disabledLock.RLock()
   834  		defer r.disabledLock.RUnlock()
   835  		return !time.Now().Before(r.disabled)
   836  	}
   837  
   838  	return true
   839  }
   840  
   841  func (r *ACLResolver) GetMergedPolicyForToken(token string) (*acl.Policy, error) {
   842  	policies, err := r.resolveTokenToPolicies(token)
   843  	if err != nil {
   844  		return nil, err
   845  	}
   846  	if len(policies) == 0 {
   847  		return nil, acl.ErrNotFound
   848  	}
   849  
   850  	return policies.Merge(r.cache, r.sentinel)
   851  }
   852  
   853  // aclFilter is used to filter results from our state store based on ACL rules
   854  // configured for the provided token.
   855  type aclFilter struct {
   856  	authorizer      acl.Authorizer
   857  	logger          *log.Logger
   858  	enforceVersion8 bool
   859  }
   860  
   861  // newACLFilter constructs a new aclFilter.
   862  func newACLFilter(authorizer acl.Authorizer, logger *log.Logger, enforceVersion8 bool) *aclFilter {
   863  	if logger == nil {
   864  		logger = log.New(os.Stderr, "", log.LstdFlags)
   865  	}
   866  	return &aclFilter{
   867  		authorizer:      authorizer,
   868  		logger:          logger,
   869  		enforceVersion8: enforceVersion8,
   870  	}
   871  }
   872  
   873  // allowNode is used to determine if a node is accessible for an ACL.
   874  func (f *aclFilter) allowNode(node string) bool {
   875  	if !f.enforceVersion8 {
   876  		return true
   877  	}
   878  	return f.authorizer.NodeRead(node)
   879  }
   880  
   881  // allowService is used to determine if a service is accessible for an ACL.
   882  func (f *aclFilter) allowService(service string) bool {
   883  	if service == "" {
   884  		return true
   885  	}
   886  
   887  	if !f.enforceVersion8 && service == structs.ConsulServiceID {
   888  		return true
   889  	}
   890  	return f.authorizer.ServiceRead(service)
   891  }
   892  
   893  // allowSession is used to determine if a session for a node is accessible for
   894  // an ACL.
   895  func (f *aclFilter) allowSession(node string) bool {
   896  	if !f.enforceVersion8 {
   897  		return true
   898  	}
   899  	return f.authorizer.SessionRead(node)
   900  }
   901  
   902  // filterHealthChecks is used to filter a set of health checks down based on
   903  // the configured ACL rules for a token.
   904  func (f *aclFilter) filterHealthChecks(checks *structs.HealthChecks) {
   905  	hc := *checks
   906  	for i := 0; i < len(hc); i++ {
   907  		check := hc[i]
   908  		if f.allowNode(check.Node) && f.allowService(check.ServiceName) {
   909  			continue
   910  		}
   911  		f.logger.Printf("[DEBUG] consul: dropping check %q from result due to ACLs", check.CheckID)
   912  		hc = append(hc[:i], hc[i+1:]...)
   913  		i--
   914  	}
   915  	*checks = hc
   916  }
   917  
   918  // filterServices is used to filter a set of services based on ACLs.
   919  func (f *aclFilter) filterServices(services structs.Services) {
   920  	for svc := range services {
   921  		if f.allowService(svc) {
   922  			continue
   923  		}
   924  		f.logger.Printf("[DEBUG] consul: dropping service %q from result due to ACLs", svc)
   925  		delete(services, svc)
   926  	}
   927  }
   928  
   929  // filterServiceNodes is used to filter a set of nodes for a given service
   930  // based on the configured ACL rules.
   931  func (f *aclFilter) filterServiceNodes(nodes *structs.ServiceNodes) {
   932  	sn := *nodes
   933  	for i := 0; i < len(sn); i++ {
   934  		node := sn[i]
   935  		if f.allowNode(node.Node) && f.allowService(node.ServiceName) {
   936  			continue
   937  		}
   938  		f.logger.Printf("[DEBUG] consul: dropping node %q from result due to ACLs", node.Node)
   939  		sn = append(sn[:i], sn[i+1:]...)
   940  		i--
   941  	}
   942  	*nodes = sn
   943  }
   944  
   945  // filterNodeServices is used to filter services on a given node base on ACLs.
   946  func (f *aclFilter) filterNodeServices(services **structs.NodeServices) {
   947  	if *services == nil {
   948  		return
   949  	}
   950  
   951  	if !f.allowNode((*services).Node.Node) {
   952  		*services = nil
   953  		return
   954  	}
   955  
   956  	for svc := range (*services).Services {
   957  		if f.allowService(svc) {
   958  			continue
   959  		}
   960  		f.logger.Printf("[DEBUG] consul: dropping service %q from result due to ACLs", svc)
   961  		delete((*services).Services, svc)
   962  	}
   963  }
   964  
   965  // filterCheckServiceNodes is used to filter nodes based on ACL rules.
   966  func (f *aclFilter) filterCheckServiceNodes(nodes *structs.CheckServiceNodes) {
   967  	csn := *nodes
   968  	for i := 0; i < len(csn); i++ {
   969  		node := csn[i]
   970  		if f.allowNode(node.Node.Node) && f.allowService(node.Service.Service) {
   971  			continue
   972  		}
   973  		f.logger.Printf("[DEBUG] consul: dropping node %q from result due to ACLs", node.Node.Node)
   974  		csn = append(csn[:i], csn[i+1:]...)
   975  		i--
   976  	}
   977  	*nodes = csn
   978  }
   979  
   980  // filterSessions is used to filter a set of sessions based on ACLs.
   981  func (f *aclFilter) filterSessions(sessions *structs.Sessions) {
   982  	s := *sessions
   983  	for i := 0; i < len(s); i++ {
   984  		session := s[i]
   985  		if f.allowSession(session.Node) {
   986  			continue
   987  		}
   988  		f.logger.Printf("[DEBUG] consul: dropping session %q from result due to ACLs", session.ID)
   989  		s = append(s[:i], s[i+1:]...)
   990  		i--
   991  	}
   992  	*sessions = s
   993  }
   994  
   995  // filterCoordinates is used to filter nodes in a coordinate dump based on ACL
   996  // rules.
   997  func (f *aclFilter) filterCoordinates(coords *structs.Coordinates) {
   998  	c := *coords
   999  	for i := 0; i < len(c); i++ {
  1000  		node := c[i].Node
  1001  		if f.allowNode(node) {
  1002  			continue
  1003  		}
  1004  		f.logger.Printf("[DEBUG] consul: dropping node %q from result due to ACLs", node)
  1005  		c = append(c[:i], c[i+1:]...)
  1006  		i--
  1007  	}
  1008  	*coords = c
  1009  }
  1010  
  1011  // filterIntentions is used to filter intentions based on ACL rules.
  1012  // We prune entries the user doesn't have access to, and we redact any tokens
  1013  // if the user doesn't have a management token.
  1014  func (f *aclFilter) filterIntentions(ixns *structs.Intentions) {
  1015  	// Management tokens can see everything with no filtering.
  1016  	if f.authorizer.ACLRead() {
  1017  		return
  1018  	}
  1019  
  1020  	// Otherwise, we need to see what the token has access to.
  1021  	ret := make(structs.Intentions, 0, len(*ixns))
  1022  	for _, ixn := range *ixns {
  1023  		// If no prefix ACL applies to this then filter it, since
  1024  		// we know at this point the user doesn't have a management
  1025  		// token, otherwise see what the policy says.
  1026  		prefix, ok := ixn.GetACLPrefix()
  1027  		if !ok || !f.authorizer.IntentionRead(prefix) {
  1028  			f.logger.Printf("[DEBUG] consul: dropping intention %q from result due to ACLs", ixn.ID)
  1029  			continue
  1030  		}
  1031  
  1032  		ret = append(ret, ixn)
  1033  	}
  1034  
  1035  	*ixns = ret
  1036  }
  1037  
  1038  // filterNodeDump is used to filter through all parts of a node dump and
  1039  // remove elements the provided ACL token cannot access.
  1040  func (f *aclFilter) filterNodeDump(dump *structs.NodeDump) {
  1041  	nd := *dump
  1042  	for i := 0; i < len(nd); i++ {
  1043  		info := nd[i]
  1044  
  1045  		// Filter nodes
  1046  		if node := info.Node; !f.allowNode(node) {
  1047  			f.logger.Printf("[DEBUG] consul: dropping node %q from result due to ACLs", node)
  1048  			nd = append(nd[:i], nd[i+1:]...)
  1049  			i--
  1050  			continue
  1051  		}
  1052  
  1053  		// Filter services
  1054  		for j := 0; j < len(info.Services); j++ {
  1055  			svc := info.Services[j].Service
  1056  			if f.allowService(svc) {
  1057  				continue
  1058  			}
  1059  			f.logger.Printf("[DEBUG] consul: dropping service %q from result due to ACLs", svc)
  1060  			info.Services = append(info.Services[:j], info.Services[j+1:]...)
  1061  			j--
  1062  		}
  1063  
  1064  		// Filter checks
  1065  		for j := 0; j < len(info.Checks); j++ {
  1066  			chk := info.Checks[j]
  1067  			if f.allowService(chk.ServiceName) {
  1068  				continue
  1069  			}
  1070  			f.logger.Printf("[DEBUG] consul: dropping check %q from result due to ACLs", chk.CheckID)
  1071  			info.Checks = append(info.Checks[:j], info.Checks[j+1:]...)
  1072  			j--
  1073  		}
  1074  	}
  1075  	*dump = nd
  1076  }
  1077  
  1078  // filterNodes is used to filter through all parts of a node list and remove
  1079  // elements the provided ACL token cannot access.
  1080  func (f *aclFilter) filterNodes(nodes *structs.Nodes) {
  1081  	n := *nodes
  1082  	for i := 0; i < len(n); i++ {
  1083  		node := n[i].Node
  1084  		if f.allowNode(node) {
  1085  			continue
  1086  		}
  1087  		f.logger.Printf("[DEBUG] consul: dropping node %q from result due to ACLs", node)
  1088  		n = append(n[:i], n[i+1:]...)
  1089  		i--
  1090  	}
  1091  	*nodes = n
  1092  }
  1093  
  1094  // redactPreparedQueryTokens will redact any tokens unless the client has a
  1095  // management token. This eases the transition to delegated authority over
  1096  // prepared queries, since it was easy to capture management tokens in Consul
  1097  // 0.6.3 and earlier, and we don't want to willy-nilly show those. This does
  1098  // have the limitation of preventing delegated non-management users from seeing
  1099  // captured tokens, but they can at least see whether or not a token is set.
  1100  func (f *aclFilter) redactPreparedQueryTokens(query **structs.PreparedQuery) {
  1101  	// Management tokens can see everything with no filtering.
  1102  	if f.authorizer.ACLWrite() {
  1103  		return
  1104  	}
  1105  
  1106  	// Let the user see if there's a blank token, otherwise we need
  1107  	// to redact it, since we know they don't have a management
  1108  	// token.
  1109  	if (*query).Token != "" {
  1110  		// Redact the token, using a copy of the query structure
  1111  		// since we could be pointed at a live instance from the
  1112  		// state store so it's not safe to modify it. Note that
  1113  		// this clone will still point to things like underlying
  1114  		// arrays in the original, but for modifying just the
  1115  		// token it will be safe to use.
  1116  		clone := *(*query)
  1117  		clone.Token = redactedToken
  1118  		*query = &clone
  1119  	}
  1120  }
  1121  
  1122  // filterPreparedQueries is used to filter prepared queries based on ACL rules.
  1123  // We prune entries the user doesn't have access to, and we redact any tokens
  1124  // if the user doesn't have a management token.
  1125  func (f *aclFilter) filterPreparedQueries(queries *structs.PreparedQueries) {
  1126  	// Management tokens can see everything with no filtering.
  1127  	if f.authorizer.ACLWrite() {
  1128  		return
  1129  	}
  1130  
  1131  	// Otherwise, we need to see what the token has access to.
  1132  	ret := make(structs.PreparedQueries, 0, len(*queries))
  1133  	for _, query := range *queries {
  1134  		// If no prefix ACL applies to this query then filter it, since
  1135  		// we know at this point the user doesn't have a management
  1136  		// token, otherwise see what the policy says.
  1137  		prefix, ok := query.GetACLPrefix()
  1138  		if !ok || !f.authorizer.PreparedQueryRead(prefix) {
  1139  			f.logger.Printf("[DEBUG] consul: dropping prepared query %q from result due to ACLs", query.ID)
  1140  			continue
  1141  		}
  1142  
  1143  		// Redact any tokens if necessary. We make a copy of just the
  1144  		// pointer so we don't mess with the caller's slice.
  1145  		final := query
  1146  		f.redactPreparedQueryTokens(&final)
  1147  		ret = append(ret, final)
  1148  	}
  1149  	*queries = ret
  1150  }
  1151  
  1152  func (f *aclFilter) redactTokenSecret(token **structs.ACLToken) {
  1153  	if token == nil || *token == nil || f == nil || f.authorizer.ACLWrite() {
  1154  		return
  1155  	}
  1156  	clone := *(*token)
  1157  	clone.SecretID = redactedToken
  1158  	*token = &clone
  1159  }
  1160  
  1161  func (f *aclFilter) redactTokenSecrets(tokens *structs.ACLTokens) {
  1162  	ret := make(structs.ACLTokens, 0, len(*tokens))
  1163  	for _, token := range *tokens {
  1164  		final := token
  1165  		f.redactTokenSecret(&final)
  1166  		ret = append(ret, final)
  1167  	}
  1168  	*tokens = ret
  1169  }
  1170  
  1171  func (r *ACLResolver) filterACLWithAuthorizer(authorizer acl.Authorizer, subj interface{}) error {
  1172  	if authorizer == nil {
  1173  		return nil
  1174  	}
  1175  	// Create the filter
  1176  	filt := newACLFilter(authorizer, r.logger, r.config.ACLEnforceVersion8)
  1177  
  1178  	switch v := subj.(type) {
  1179  	case *structs.CheckServiceNodes:
  1180  		filt.filterCheckServiceNodes(v)
  1181  
  1182  	case *structs.IndexedCheckServiceNodes:
  1183  		filt.filterCheckServiceNodes(&v.Nodes)
  1184  
  1185  	case *structs.IndexedCoordinates:
  1186  		filt.filterCoordinates(&v.Coordinates)
  1187  
  1188  	case *structs.IndexedHealthChecks:
  1189  		filt.filterHealthChecks(&v.HealthChecks)
  1190  
  1191  	case *structs.IndexedIntentions:
  1192  		filt.filterIntentions(&v.Intentions)
  1193  
  1194  	case *structs.IndexedNodeDump:
  1195  		filt.filterNodeDump(&v.Dump)
  1196  
  1197  	case *structs.IndexedNodes:
  1198  		filt.filterNodes(&v.Nodes)
  1199  
  1200  	case *structs.IndexedNodeServices:
  1201  		filt.filterNodeServices(&v.NodeServices)
  1202  
  1203  	case *structs.IndexedServiceNodes:
  1204  		filt.filterServiceNodes(&v.ServiceNodes)
  1205  
  1206  	case *structs.IndexedServices:
  1207  		filt.filterServices(v.Services)
  1208  
  1209  	case *structs.IndexedSessions:
  1210  		filt.filterSessions(&v.Sessions)
  1211  
  1212  	case *structs.IndexedPreparedQueries:
  1213  		filt.filterPreparedQueries(&v.Queries)
  1214  
  1215  	case **structs.PreparedQuery:
  1216  		filt.redactPreparedQueryTokens(v)
  1217  
  1218  	case *structs.ACLTokens:
  1219  		filt.redactTokenSecrets(v)
  1220  
  1221  	case **structs.ACLToken:
  1222  		filt.redactTokenSecret(v)
  1223  
  1224  	default:
  1225  		panic(fmt.Errorf("Unhandled type passed to ACL filter: %#v", subj))
  1226  	}
  1227  
  1228  	return nil
  1229  }
  1230  
  1231  // filterACL is used to filter results from our service catalog based on the
  1232  // rules configured for the provided token.
  1233  func (r *ACLResolver) filterACL(token string, subj interface{}) error {
  1234  	// Get the ACL from the token
  1235  	authorizer, err := r.ResolveToken(token)
  1236  	if err != nil {
  1237  		return err
  1238  	}
  1239  
  1240  	// Fast path if ACLs are not enabled
  1241  	if authorizer == nil {
  1242  		return nil
  1243  	}
  1244  
  1245  	return r.filterACLWithAuthorizer(authorizer, subj)
  1246  }
  1247  
  1248  // vetRegisterWithACL applies the given ACL's policy to the catalog update and
  1249  // determines if it is allowed. Since the catalog register request is so
  1250  // dynamic, this is a pretty complex algorithm and was worth breaking out of the
  1251  // endpoint. The NodeServices record for the node must be supplied, and can be
  1252  // nil.
  1253  //
  1254  // This is a bit racy because we have to check the state store outside of a
  1255  // transaction. It's the best we can do because we don't want to flow ACL
  1256  // checking down there. The node information doesn't change in practice, so this
  1257  // will be fine. If we expose ways to change node addresses in a later version,
  1258  // then we should split the catalog API at the node and service level so we can
  1259  // address this race better (even then it would be super rare, and would at
  1260  // worst let a service update revert a recent node update, so it doesn't open up
  1261  // too much abuse).
  1262  func vetRegisterWithACL(rule acl.Authorizer, subj *structs.RegisterRequest,
  1263  	ns *structs.NodeServices) error {
  1264  	// Fast path if ACLs are not enabled.
  1265  	if rule == nil {
  1266  		return nil
  1267  	}
  1268  
  1269  	// This gets called potentially from a few spots so we save it and
  1270  	// return the structure we made if we have it.
  1271  	var memo map[string]interface{}
  1272  	scope := func() map[string]interface{} {
  1273  		if memo != nil {
  1274  			return memo
  1275  		}
  1276  
  1277  		node := &api.Node{
  1278  			ID:              string(subj.ID),
  1279  			Node:            subj.Node,
  1280  			Address:         subj.Address,
  1281  			Datacenter:      subj.Datacenter,
  1282  			TaggedAddresses: subj.TaggedAddresses,
  1283  			Meta:            subj.NodeMeta,
  1284  		}
  1285  
  1286  		var service *api.AgentService
  1287  		if subj.Service != nil {
  1288  			service = &api.AgentService{
  1289  				ID:                subj.Service.ID,
  1290  				Service:           subj.Service.Service,
  1291  				Tags:              subj.Service.Tags,
  1292  				Meta:              subj.Service.Meta,
  1293  				Address:           subj.Service.Address,
  1294  				Port:              subj.Service.Port,
  1295  				EnableTagOverride: subj.Service.EnableTagOverride,
  1296  			}
  1297  		}
  1298  
  1299  		memo = sentinel.ScopeCatalogUpsert(node, service)
  1300  		return memo
  1301  	}
  1302  
  1303  	// Vet the node info. This allows service updates to re-post the required
  1304  	// node info for each request without having to have node "write"
  1305  	// privileges.
  1306  	needsNode := ns == nil || subj.ChangesNode(ns.Node)
  1307  
  1308  	if needsNode && !rule.NodeWrite(subj.Node, scope) {
  1309  		return acl.ErrPermissionDenied
  1310  	}
  1311  
  1312  	// Vet the service change. This includes making sure they can register
  1313  	// the given service, and that we can write to any existing service that
  1314  	// is being modified by id (if any).
  1315  	if subj.Service != nil {
  1316  		if !rule.ServiceWrite(subj.Service.Service, scope) {
  1317  			return acl.ErrPermissionDenied
  1318  		}
  1319  
  1320  		if ns != nil {
  1321  			other, ok := ns.Services[subj.Service.ID]
  1322  
  1323  			// This is effectively a delete, so we DO NOT apply the
  1324  			// sentinel scope to the service we are overwriting, just
  1325  			// the regular ACL policy.
  1326  			if ok && !rule.ServiceWrite(other.Service, nil) {
  1327  				return acl.ErrPermissionDenied
  1328  			}
  1329  		}
  1330  	}
  1331  
  1332  	// Make sure that the member was flattened before we got there. This
  1333  	// keeps us from having to verify this check as well.
  1334  	if subj.Check != nil {
  1335  		return fmt.Errorf("check member must be nil")
  1336  	}
  1337  
  1338  	// Vet the checks. Node-level checks require node write, and
  1339  	// service-level checks require service write.
  1340  	for _, check := range subj.Checks {
  1341  		// Make sure that the node matches - we don't allow you to mix
  1342  		// checks from other nodes because we'd have to pull a bunch
  1343  		// more state store data to check this. If ACLs are enabled then
  1344  		// we simply require them to match in a given request. There's a
  1345  		// note in state_store.go to ban this down there in Consul 0.8,
  1346  		// but it's good to leave this here because it's required for
  1347  		// correctness wrt. ACLs.
  1348  		if check.Node != subj.Node {
  1349  			return fmt.Errorf("Node '%s' for check '%s' doesn't match register request node '%s'",
  1350  				check.Node, check.CheckID, subj.Node)
  1351  		}
  1352  
  1353  		// Node-level check.
  1354  		if check.ServiceID == "" {
  1355  			if !rule.NodeWrite(subj.Node, scope) {
  1356  				return acl.ErrPermissionDenied
  1357  			}
  1358  			continue
  1359  		}
  1360  
  1361  		// Service-level check, check the common case where it
  1362  		// matches the service part of this request, which has
  1363  		// already been vetted above, and might be being registered
  1364  		// along with its checks.
  1365  		if subj.Service != nil && subj.Service.ID == check.ServiceID {
  1366  			continue
  1367  		}
  1368  
  1369  		// Service-level check for some other service. Make sure they've
  1370  		// got write permissions for that service.
  1371  		if ns == nil {
  1372  			return fmt.Errorf("Unknown service '%s' for check '%s'", check.ServiceID, check.CheckID)
  1373  		}
  1374  
  1375  		other, ok := ns.Services[check.ServiceID]
  1376  		if !ok {
  1377  			return fmt.Errorf("Unknown service '%s' for check '%s'", check.ServiceID, check.CheckID)
  1378  		}
  1379  
  1380  		// We are only adding a check here, so we don't add the scope,
  1381  		// since the sentinel policy doesn't apply to adding checks at
  1382  		// this time.
  1383  		if !rule.ServiceWrite(other.Service, nil) {
  1384  			return acl.ErrPermissionDenied
  1385  		}
  1386  	}
  1387  
  1388  	return nil
  1389  }
  1390  
  1391  // vetDeregisterWithACL applies the given ACL's policy to the catalog update and
  1392  // determines if it is allowed. Since the catalog deregister request is so
  1393  // dynamic, this is a pretty complex algorithm and was worth breaking out of the
  1394  // endpoint. The NodeService for the referenced service must be supplied, and can
  1395  // be nil; similar for the HealthCheck for the referenced health check.
  1396  func vetDeregisterWithACL(rule acl.Authorizer, subj *structs.DeregisterRequest,
  1397  	ns *structs.NodeService, nc *structs.HealthCheck) error {
  1398  
  1399  	// Fast path if ACLs are not enabled.
  1400  	if rule == nil {
  1401  		return nil
  1402  	}
  1403  
  1404  	// We don't apply sentinel in this path, since at this time sentinel
  1405  	// only applies to create and update operations.
  1406  
  1407  	// This order must match the code in applyRegister() in fsm.go since it
  1408  	// also evaluates things in this order, and will ignore fields based on
  1409  	// this precedence. This lets us also ignore them from an ACL perspective.
  1410  	if subj.ServiceID != "" {
  1411  		if ns == nil {
  1412  			return fmt.Errorf("Unknown service '%s'", subj.ServiceID)
  1413  		}
  1414  		if !rule.ServiceWrite(ns.Service, nil) {
  1415  			return acl.ErrPermissionDenied
  1416  		}
  1417  	} else if subj.CheckID != "" {
  1418  		if nc == nil {
  1419  			return fmt.Errorf("Unknown check '%s'", subj.CheckID)
  1420  		}
  1421  		if nc.ServiceID != "" {
  1422  			if !rule.ServiceWrite(nc.ServiceName, nil) {
  1423  				return acl.ErrPermissionDenied
  1424  			}
  1425  		} else {
  1426  			if !rule.NodeWrite(subj.Node, nil) {
  1427  				return acl.ErrPermissionDenied
  1428  			}
  1429  		}
  1430  	} else {
  1431  		if !rule.NodeWrite(subj.Node, nil) {
  1432  			return acl.ErrPermissionDenied
  1433  		}
  1434  	}
  1435  
  1436  	return nil
  1437  }
  1438  
  1439  // vetNodeTxnOp applies the given ACL policy to a node transaction operation.
  1440  func vetNodeTxnOp(op *structs.TxnNodeOp, rule acl.Authorizer) error {
  1441  	// Fast path if ACLs are not enabled.
  1442  	if rule == nil {
  1443  		return nil
  1444  	}
  1445  
  1446  	node := op.Node
  1447  
  1448  	n := &api.Node{
  1449  		Node:            node.Node,
  1450  		ID:              string(node.ID),
  1451  		Address:         node.Address,
  1452  		Datacenter:      node.Datacenter,
  1453  		TaggedAddresses: node.TaggedAddresses,
  1454  		Meta:            node.Meta,
  1455  	}
  1456  
  1457  	// Sentinel doesn't apply to deletes, only creates/updates, so we don't need the scopeFn.
  1458  	var scope func() map[string]interface{}
  1459  	if op.Verb != api.NodeDelete && op.Verb != api.NodeDeleteCAS {
  1460  		scope = func() map[string]interface{} {
  1461  			return sentinel.ScopeCatalogUpsert(n, nil)
  1462  		}
  1463  	}
  1464  
  1465  	if rule != nil && !rule.NodeWrite(node.Node, scope) {
  1466  		return acl.ErrPermissionDenied
  1467  	}
  1468  
  1469  	return nil
  1470  }
  1471  
  1472  // vetServiceTxnOp applies the given ACL policy to a service transaction operation.
  1473  func vetServiceTxnOp(op *structs.TxnServiceOp, rule acl.Authorizer) error {
  1474  	// Fast path if ACLs are not enabled.
  1475  	if rule == nil {
  1476  		return nil
  1477  	}
  1478  
  1479  	service := op.Service
  1480  
  1481  	n := &api.Node{Node: op.Node}
  1482  	svc := &api.AgentService{
  1483  		ID:                service.ID,
  1484  		Service:           service.Service,
  1485  		Tags:              service.Tags,
  1486  		Meta:              service.Meta,
  1487  		Address:           service.Address,
  1488  		Port:              service.Port,
  1489  		EnableTagOverride: service.EnableTagOverride,
  1490  	}
  1491  	var scope func() map[string]interface{}
  1492  	if op.Verb != api.ServiceDelete && op.Verb != api.ServiceDeleteCAS {
  1493  		scope = func() map[string]interface{} {
  1494  			return sentinel.ScopeCatalogUpsert(n, svc)
  1495  		}
  1496  	}
  1497  	if !rule.ServiceWrite(service.Service, scope) {
  1498  		return acl.ErrPermissionDenied
  1499  	}
  1500  
  1501  	return nil
  1502  }
  1503  
  1504  // vetCheckTxnOp applies the given ACL policy to a check transaction operation.
  1505  func vetCheckTxnOp(op *structs.TxnCheckOp, rule acl.Authorizer) error {
  1506  	// Fast path if ACLs are not enabled.
  1507  	if rule == nil {
  1508  		return nil
  1509  	}
  1510  
  1511  	n := &api.Node{Node: op.Check.Node}
  1512  	svc := &api.AgentService{
  1513  		ID:      op.Check.ServiceID,
  1514  		Service: op.Check.ServiceID,
  1515  		Tags:    op.Check.ServiceTags,
  1516  	}
  1517  	var scope func() map[string]interface{}
  1518  	if op.Check.ServiceID == "" {
  1519  		// Node-level check.
  1520  		if op.Verb == api.CheckDelete || op.Verb == api.CheckDeleteCAS {
  1521  			scope = func() map[string]interface{} {
  1522  				return sentinel.ScopeCatalogUpsert(n, svc)
  1523  			}
  1524  		}
  1525  		if !rule.NodeWrite(op.Check.Node, scope) {
  1526  			return acl.ErrPermissionDenied
  1527  		}
  1528  	} else {
  1529  		// Service-level check.
  1530  		if op.Verb == api.CheckDelete || op.Verb == api.CheckDeleteCAS {
  1531  			scope = func() map[string]interface{} {
  1532  				return sentinel.ScopeCatalogUpsert(n, svc)
  1533  			}
  1534  		}
  1535  		if !rule.ServiceWrite(op.Check.ServiceName, scope) {
  1536  			return acl.ErrPermissionDenied
  1537  		}
  1538  	}
  1539  
  1540  	return nil
  1541  }