Sync over
This commit is contained in:
parent
3c6fe40a91
commit
b7ffe7ec99
131
vault/core.go
131
vault/core.go
|
@ -51,6 +51,10 @@ const (
|
|||
// the currently elected leader.
|
||||
coreLeaderPrefix = "core/leader/"
|
||||
|
||||
// knownPrimaryAddrsPrefix is used to store last-known cluster address
|
||||
// information for primaries
|
||||
knownPrimaryAddrsPrefix = "core/primary-addrs/"
|
||||
|
||||
// lockRetryInterval is the interval we re-attempt to acquire the
|
||||
// HA lock if an error is encountered
|
||||
lockRetryInterval = 10 * time.Second
|
||||
|
@ -104,6 +108,9 @@ var (
|
|||
startReplication = startReplicationImpl
|
||||
stopReplication = stopReplicationImpl
|
||||
LastRemoteWAL = lastRemoteWALImpl
|
||||
// A package-available logger function, mainly to have access in ACL for
|
||||
// error conditions
|
||||
vlogger log.Logger
|
||||
)
|
||||
|
||||
// NonFatalError is an error that can be returned during NewCore that should be
|
||||
|
@ -344,6 +351,11 @@ type Core struct {
|
|||
// CORS Information
|
||||
corsConfig *CORSConfig
|
||||
|
||||
// The active set of upstream cluster addresses; stored via the Echo
|
||||
// mechanism, loaded by the balancer
|
||||
atomicPrimaryClusterAddrs *atomic.Value
|
||||
|
||||
atomicPrimaryFailoverAddrs *atomic.Value
|
||||
// replicationState keeps the current replication state cached for quick
|
||||
// lookup
|
||||
replicationState consts.ReplicationState
|
||||
|
@ -455,6 +467,7 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
|||
if conf.Logger == nil {
|
||||
conf.Logger = logformat.NewVaultLogger(log.LevelTrace)
|
||||
}
|
||||
vlogger = conf.Logger
|
||||
|
||||
// Setup the core
|
||||
c := &Core{
|
||||
|
@ -476,6 +489,8 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
|||
clusterPeerClusterAddrsCache: cache.New(3*heartbeatInterval, time.Second),
|
||||
enableMlock: !conf.DisableMlock,
|
||||
rawEnabled: conf.EnableRaw,
|
||||
atomicPrimaryClusterAddrs: new(atomic.Value),
|
||||
atomicPrimaryFailoverAddrs: new(atomic.Value),
|
||||
}
|
||||
|
||||
if conf.ClusterCipherSuites != "" {
|
||||
|
@ -486,18 +501,27 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
|||
c.clusterCipherSuites = suites
|
||||
}
|
||||
|
||||
c.corsConfig = &CORSConfig{core: c}
|
||||
// Load CORS config and provide a value for the core field.
|
||||
c.corsConfig = &CORSConfig{core: c}
|
||||
|
||||
phys := conf.Physical
|
||||
_, txnOK := conf.Physical.(physical.Transactional)
|
||||
// Wrap the physical backend in a cache layer if enabled and not already wrapped
|
||||
if _, isCache := conf.Physical.(*physical.Cache); !conf.DisableCache && !isCache {
|
||||
if c.seal == nil {
|
||||
c.seal = &DefaultSeal{}
|
||||
}
|
||||
c.seal.SetCore(c)
|
||||
|
||||
var ok bool
|
||||
|
||||
// Wrap the physical backend in a cache layer if enabled
|
||||
if !conf.DisableCache {
|
||||
if txnOK {
|
||||
c.physical = physical.NewTransactionalCache(conf.Physical, conf.CacheSize, conf.Logger)
|
||||
c.physical = physical.NewTransactionalCache(phys, conf.CacheSize, conf.Logger)
|
||||
} else {
|
||||
c.physical = physical.NewCache(conf.Physical, conf.CacheSize, conf.Logger)
|
||||
c.physical = physical.NewCache(phys, conf.CacheSize, conf.Logger)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !conf.DisableMlock {
|
||||
// Ensure our memory usage is locked into physical RAM
|
||||
|
@ -546,7 +570,7 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
|||
for k, f := range conf.LogicalBackends {
|
||||
logicalBackends[k] = f
|
||||
}
|
||||
_, ok := logicalBackends["kv"]
|
||||
_, ok = logicalBackends["kv"]
|
||||
if !ok {
|
||||
logicalBackends["kv"] = PassthroughBackendFactory
|
||||
}
|
||||
|
@ -580,16 +604,7 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
|||
}
|
||||
c.auditBackends = auditBackends
|
||||
|
||||
if c.seal == nil {
|
||||
c.seal = &DefaultSeal{}
|
||||
}
|
||||
c.seal.SetCore(c)
|
||||
|
||||
// Attempt unsealing with stored keys; if there are no stored keys this
|
||||
// returns nil, otherwise returns nil or an error
|
||||
storedKeyErr := c.UnsealWithStoredKeys()
|
||||
|
||||
return c, storedKeyErr
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// Shutdown is invoked when the Vault instance is about to be terminated. It
|
||||
|
@ -724,17 +739,34 @@ func (c *Core) fetchACLTokenEntryAndEntity(clientToken string) (*ACL, *TokenEntr
|
|||
return acl, te, entity, nil
|
||||
}
|
||||
|
||||
func (c *Core) checkToken(req *logical.Request) (*logical.Auth, *TokenEntry, error) {
|
||||
func (c *Core) checkToken(req *logical.Request, unauth bool) (*logical.Auth, *TokenEntry, error) {
|
||||
defer metrics.MeasureSince([]string{"core", "check_token"}, time.Now())
|
||||
|
||||
acl, te, _, err := c.fetchACLTokenEntryAndEntity(req.ClientToken)
|
||||
if err != nil {
|
||||
return nil, te, err
|
||||
var acl *ACL
|
||||
var te *TokenEntry
|
||||
var entity *identity.Entity
|
||||
var err error
|
||||
|
||||
// Even if unauth, if a token is provided, there's little reason not to
|
||||
// gather as much info as possible for the audit log and to e.g. control
|
||||
// trace mode for EGPs.
|
||||
if !unauth || (unauth && req.ClientToken != "") {
|
||||
acl, te, entity, err = c.fetchACLTokenEntryAndEntity(req.ClientToken)
|
||||
// In the unauth case we don't want to fail the command, since it's
|
||||
// unauth, we just have no information to attach to the request, so
|
||||
// ignore errors...this was best-effort anyways
|
||||
if err != nil && !unauth {
|
||||
return nil, te, err
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a root protected path
|
||||
rootPath := c.router.RootPath(req.Path)
|
||||
|
||||
if rootPath && unauth {
|
||||
return nil, nil, errors.New("cannot access root path in unauthenticated request")
|
||||
}
|
||||
|
||||
// When we receive a write of either type, rather than require clients to
|
||||
// PUT/POST and trust the operation, we ask the backend to give us the real
|
||||
// skinny -- if the backend implements an existence check, it can tell us
|
||||
|
@ -788,12 +820,14 @@ func (c *Core) checkToken(req *logical.Request) (*logical.Auth, *TokenEntry, err
|
|||
|
||||
// Check the standard non-root ACLs. Return the token entry if it's not
|
||||
// allowed so we can decrement the use count.
|
||||
allowed, rootPrivs := acl.AllowOperation(req)
|
||||
if !allowed {
|
||||
// Return auth for audit logging even if not allowed
|
||||
return auth, te, logical.ErrPermissionDenied
|
||||
authResults := c.performPolicyChecks(acl, te, req, entity, &PolicyCheckOpts{
|
||||
Unauth: unauth,
|
||||
RootPrivsRequired: rootPath,
|
||||
})
|
||||
if authResults.Error.ErrorOrNil() != nil {
|
||||
return auth, te, authResults.Error
|
||||
}
|
||||
if rootPath && !rootPrivs {
|
||||
if !authResults.Allowed {
|
||||
// Return auth for audit logging even if not allowed
|
||||
return auth, te, logical.ErrPermissionDenied
|
||||
}
|
||||
|
@ -1147,7 +1181,7 @@ func (c *Core) sealInitCommon(req *logical.Request) (retErr error) {
|
|||
}
|
||||
|
||||
// Validate the token is a root token
|
||||
acl, te, _, err := c.fetchACLTokenEntryAndEntity(req.ClientToken)
|
||||
acl, te, entity, err := c.fetchACLTokenEntryAndEntity(req.ClientToken)
|
||||
if err != nil {
|
||||
// Since there is no token store in standby nodes, sealing cannot
|
||||
// be done. Ideally, the request has to be forwarded to leader node
|
||||
|
@ -1210,15 +1244,15 @@ func (c *Core) sealInitCommon(req *logical.Request) (retErr error) {
|
|||
}
|
||||
|
||||
// Verify that this operation is allowed
|
||||
allowed, rootPrivs := acl.AllowOperation(req)
|
||||
if !allowed {
|
||||
retErr = multierror.Append(retErr, logical.ErrPermissionDenied)
|
||||
authResults := c.performPolicyChecks(acl, te, req, entity, &PolicyCheckOpts{
|
||||
RootPrivsRequired: true,
|
||||
})
|
||||
if authResults.Error.ErrorOrNil() != nil {
|
||||
retErr = multierror.Append(retErr, authResults.Error)
|
||||
c.stateLock.RUnlock()
|
||||
return retErr
|
||||
}
|
||||
|
||||
// We always require root privileges for this operation
|
||||
if !rootPrivs {
|
||||
if !authResults.Allowed {
|
||||
retErr = multierror.Append(retErr, logical.ErrPermissionDenied)
|
||||
c.stateLock.RUnlock()
|
||||
return retErr
|
||||
|
@ -1266,7 +1300,7 @@ func (c *Core) StepDown(req *logical.Request) (retErr error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
acl, te, _, err := c.fetchACLTokenEntryAndEntity(req.ClientToken)
|
||||
acl, te, entity, err := c.fetchACLTokenEntryAndEntity(req.ClientToken)
|
||||
if err != nil {
|
||||
retErr = multierror.Append(retErr, err)
|
||||
return retErr
|
||||
|
@ -1313,14 +1347,14 @@ func (c *Core) StepDown(req *logical.Request) (retErr error) {
|
|||
}
|
||||
|
||||
// Verify that this operation is allowed
|
||||
allowed, rootPrivs := acl.AllowOperation(req)
|
||||
if !allowed {
|
||||
retErr = multierror.Append(retErr, logical.ErrPermissionDenied)
|
||||
authResults := c.performPolicyChecks(acl, te, req, entity, &PolicyCheckOpts{
|
||||
RootPrivsRequired: true,
|
||||
})
|
||||
if authResults.Error.ErrorOrNil() != nil {
|
||||
retErr = multierror.Append(retErr, authResults.Error)
|
||||
return retErr
|
||||
}
|
||||
|
||||
// We always require root privileges for this operation
|
||||
if !rootPrivs {
|
||||
if !authResults.Allowed {
|
||||
retErr = multierror.Append(retErr, logical.ErrPermissionDenied)
|
||||
return retErr
|
||||
}
|
||||
|
@ -1463,6 +1497,9 @@ func (c *Core) postUnseal() (retErr error) {
|
|||
if err := c.setupAudits(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.loadIdentityStoreArtifacts(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.setupAuditedHeadersConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1967,9 +2004,7 @@ func (c *Core) ReplicationState() consts.ReplicationState {
|
|||
}
|
||||
|
||||
func (c *Core) SealAccess() *SealAccess {
|
||||
sa := &SealAccess{}
|
||||
sa.SetSeal(c.seal)
|
||||
return sa
|
||||
return NewSealAccess(c.seal)
|
||||
}
|
||||
|
||||
func (c *Core) Logger() log.Logger {
|
||||
|
@ -1989,3 +2024,15 @@ func (c *Core) AuditedHeadersConfig() *AuditedHeadersConfig {
|
|||
func lastRemoteWALImpl(c *Core) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (c *Core) BarrierEncryptorAccess() *BarrierEncryptorAccess {
|
||||
return NewBarrierEncryptorAccess(c.barrier)
|
||||
}
|
||||
|
||||
func (c *Core) PhysicalAccess() *physical.PhysicalAccess {
|
||||
return physical.NewPhysicalAccess(c.physical)
|
||||
}
|
||||
|
||||
func (c *Core) RouterAccess() *RouterAccess {
|
||||
return NewRouterAccess(c)
|
||||
}
|
||||
|
|
|
@ -488,7 +488,7 @@ func TestCore_HandleRequest_RootPath_WithSudo(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp != nil {
|
||||
if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
}
|
||||
|
||||
|
@ -546,7 +546,7 @@ func TestCore_HandleRequest_PermissionAllowed(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp != nil {
|
||||
if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
}
|
||||
|
||||
|
@ -873,6 +873,9 @@ func TestCore_HandleRequest_CreateToken_Lease(t *testing.T) {
|
|||
}
|
||||
|
||||
// Ensure we got a new client token back
|
||||
if resp.IsError() {
|
||||
t.Fatalf("err: %v %v", err, *resp)
|
||||
}
|
||||
clientToken := resp.Auth.ClientToken
|
||||
if clientToken == "" {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
|
@ -1927,7 +1930,7 @@ path "secret/*" {
|
|||
`
|
||||
|
||||
ps := c.policyStore
|
||||
policy, _ := Parse(secretWritingPolicy)
|
||||
policy, _ := ParseACLPolicy(secretWritingPolicy)
|
||||
if err := ps.SetPolicy(policy); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ var StdAllowedHeaders = []string{
|
|||
"X-Vault-Token",
|
||||
"X-Vault-Wrap-Format",
|
||||
"X-Vault-Wrap-TTL",
|
||||
"X-Vault-Policy-Override",
|
||||
}
|
||||
|
||||
// CORSConfig stores the state of the CORS configuration.
|
||||
|
|
|
@ -54,8 +54,8 @@ func (d dynamicSystemView) SudoPrivilege(path string, token string) bool {
|
|||
req := new(logical.Request)
|
||||
req.Operation = logical.ReadOperation
|
||||
req.Path = path
|
||||
_, rootPrivs := acl.AllowOperation(req)
|
||||
return rootPrivs
|
||||
authResults := acl.AllowOperation(req)
|
||||
return authResults.RootPrivs
|
||||
}
|
||||
|
||||
// TTLsByPath returns the default and max TTLs corresponding to a particular
|
||||
|
|
|
@ -251,6 +251,7 @@ func (c *Core) Initialize(initParams *InitParams) (*InitResult, error) {
|
|||
return results, nil
|
||||
}
|
||||
|
||||
// UnsealWithStoredKeys performs auto-unseal using stored keys.
|
||||
func (c *Core) UnsealWithStoredKeys() error {
|
||||
if !c.seal.StoredKeysSupported() {
|
||||
return nil
|
||||
|
@ -297,6 +298,6 @@ func (c *Core) UnsealWithStoredKeys() error {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue