mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 10:37:56 +00:00 
			
		
		
		
	Don't write salts in initialization, look up on demand (#2702)
This commit is contained in:
		| @@ -1,7 +1,6 @@ | ||||
| package appId | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"sync" | ||||
|  | ||||
| 	"github.com/hashicorp/vault/helper/salt" | ||||
| @@ -72,8 +71,6 @@ func Backend(conf *logical.BackendConfig) (*framework.Backend, error) { | ||||
|  | ||||
| 		AuthRenew: b.pathLoginRenew, | ||||
|  | ||||
| 		Init: b.initialize, | ||||
|  | ||||
| 		Invalidate: b.invalidate, | ||||
| 	} | ||||
|  | ||||
| @@ -85,110 +82,45 @@ func Backend(conf *logical.BackendConfig) (*framework.Backend, error) { | ||||
| type backend struct { | ||||
| 	*framework.Backend | ||||
|  | ||||
| 	Salt      *salt.Salt | ||||
| 	salt      *salt.Salt | ||||
| 	SaltMutex sync.RWMutex | ||||
| 	view      logical.Storage | ||||
| 	MapAppId  *framework.PolicyMap | ||||
| 	MapUserId *framework.PathMap | ||||
| } | ||||
|  | ||||
| func (b *backend) initialize() error { | ||||
| func (b *backend) Salt() (*salt.Salt, error) { | ||||
| 	b.SaltMutex.RLock() | ||||
| 	if b.salt != nil { | ||||
| 		defer b.SaltMutex.RUnlock() | ||||
| 		return b.salt, nil | ||||
| 	} | ||||
| 	b.SaltMutex.RUnlock() | ||||
| 	b.SaltMutex.Lock() | ||||
| 	defer b.SaltMutex.Unlock() | ||||
| 	if b.salt != nil { | ||||
| 		return b.salt, nil | ||||
| 	} | ||||
| 	salt, err := salt.NewSalt(b.view, &salt.Config{ | ||||
| 		HashFunc: salt.SHA1Hash, | ||||
| 		Location: salt.DefaultLocation, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		b.SaltMutex.Unlock() | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	b.Salt = salt | ||||
| 	b.SaltMutex.Unlock() | ||||
| 	b.salt = salt | ||||
| 	b.MapAppId.SaltFunc = b.Salt | ||||
| 	b.MapUserId.SaltFunc = b.Salt | ||||
|  | ||||
| 	b.MapAppId.Salt = salt | ||||
| 	b.MapAppId.SaltMutex = &b.SaltMutex | ||||
| 	b.MapUserId.Salt = salt | ||||
| 	b.MapUserId.SaltMutex = &b.SaltMutex | ||||
|  | ||||
| 	// Since the salt is new in 0.2, we need to handle this by migrating | ||||
| 	// any existing keys to use the salt. We can deprecate this eventually, | ||||
| 	// but for now we want a smooth upgrade experience by automatically | ||||
| 	// upgrading to use salting. | ||||
| 	if salt.DidGenerate() { | ||||
| 		if err := b.upgradeToSalted(b.view); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // upgradeToSalted is used to upgrade the non-salted keys prior to | ||||
| // Vault 0.2 to be salted. This is done on mount time and is only | ||||
| // done once. It can be deprecated eventually, but should be around | ||||
| // long enough for all 0.1.x users to upgrade. | ||||
| func (b *backend) upgradeToSalted(view logical.Storage) error { | ||||
| 	// Create a copy of MapAppId that does not use a Salt | ||||
| 	nonSaltedAppId := new(framework.PathMap) | ||||
| 	*nonSaltedAppId = b.MapAppId.PathMap | ||||
| 	nonSaltedAppId.Salt = nil | ||||
|  | ||||
| 	// Get the list of app-ids | ||||
| 	keys, err := b.MapAppId.List(view, "") | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to list app-ids: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Upgrade all the existing keys | ||||
| 	for _, key := range keys { | ||||
| 		val, err := nonSaltedAppId.Get(view, key) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("failed to read app-id: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		if err := b.MapAppId.Put(view, key, val); err != nil { | ||||
| 			return fmt.Errorf("failed to write app-id: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		if err := nonSaltedAppId.Delete(view, key); err != nil { | ||||
| 			return fmt.Errorf("failed to delete app-id: %v", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Create a copy of MapUserId that does not use a Salt | ||||
| 	nonSaltedUserId := new(framework.PathMap) | ||||
| 	*nonSaltedUserId = *b.MapUserId | ||||
| 	nonSaltedUserId.Salt = nil | ||||
|  | ||||
| 	// Get the list of user-ids | ||||
| 	keys, err = b.MapUserId.List(view, "") | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to list user-ids: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Upgrade all the existing keys | ||||
| 	for _, key := range keys { | ||||
| 		val, err := nonSaltedUserId.Get(view, key) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("failed to read user-id: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		if err := b.MapUserId.Put(view, key, val); err != nil { | ||||
| 			return fmt.Errorf("failed to write user-id: %v", err) | ||||
| 		} | ||||
|  | ||||
| 		if err := nonSaltedUserId.Delete(view, key); err != nil { | ||||
| 			return fmt.Errorf("failed to delete user-id: %v", err) | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| 	return salt, nil | ||||
| } | ||||
|  | ||||
| func (b *backend) invalidate(key string) { | ||||
| 	switch key { | ||||
| 	case salt.DefaultLocation: | ||||
| 		// reread the salt | ||||
| 		b.initialize() | ||||
| 		b.SaltMutex.Lock() | ||||
| 		defer b.SaltMutex.Unlock() | ||||
| 		b.salt = nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -51,70 +51,6 @@ func TestBackend_displayName(t *testing.T) { | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // Verify that we are able to update from non-salted (<0.2) to | ||||
| // using a Salt for the paths | ||||
| func TestBackend_upgradeToSalted(t *testing.T) { | ||||
| 	inm := new(logical.InmemStorage) | ||||
|  | ||||
| 	// Create some fake keys | ||||
| 	se, _ := logical.StorageEntryJSON("struct/map/app-id/foo", | ||||
| 		map[string]string{"value": "test"}) | ||||
| 	inm.Put(se) | ||||
| 	se, _ = logical.StorageEntryJSON("struct/map/user-id/bar", | ||||
| 		map[string]string{"value": "foo"}) | ||||
| 	inm.Put(se) | ||||
|  | ||||
| 	// Initialize the backend, this should do the automatic upgrade | ||||
| 	conf := &logical.BackendConfig{ | ||||
| 		StorageView: inm, | ||||
| 	} | ||||
| 	backend, err := Factory(conf) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	err = backend.Initialize() | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Check the keys have been upgraded | ||||
| 	out, err := inm.Get("struct/map/app-id/foo") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	if out != nil { | ||||
| 		t.Fatalf("unexpected key") | ||||
| 	} | ||||
| 	out, err = inm.Get("struct/map/user-id/bar") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	if out != nil { | ||||
| 		t.Fatalf("unexpected key") | ||||
| 	} | ||||
|  | ||||
| 	// Backend should still be able to resolve | ||||
| 	req := logical.TestRequest(t, logical.ReadOperation, "map/app-id/foo") | ||||
| 	req.Storage = inm | ||||
| 	resp, err := backend.HandleRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	if resp.Data["value"] != "test" { | ||||
| 		t.Fatalf("bad: %#v", resp) | ||||
| 	} | ||||
|  | ||||
| 	req = logical.TestRequest(t, logical.ReadOperation, "map/user-id/bar") | ||||
| 	req.Storage = inm | ||||
| 	resp, err = backend.HandleRequest(req) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	if resp.Data["value"] != "foo" { | ||||
| 		t.Fatalf("bad: %#v", resp) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testAccStepMapAppId(t *testing.T) logicaltest.TestStep { | ||||
| 	return logicaltest.TestStep{ | ||||
| 		Operation: logical.UpdateOperation, | ||||
|   | ||||
| @@ -93,31 +93,40 @@ func Backend(conf *logical.BackendConfig) (*backend, error) { | ||||
| 				pathTidySecretID(b), | ||||
| 			}, | ||||
| 		), | ||||
| 		Init:       b.initialize, | ||||
| 		Invalidate: b.invalidate, | ||||
| 	} | ||||
| 	return b, nil | ||||
| } | ||||
|  | ||||
| func (b *backend) initialize() error { | ||||
| func (b *backend) Salt() (*salt.Salt, error) { | ||||
| 	b.saltMutex.RLock() | ||||
| 	if b.salt != nil { | ||||
| 		defer b.saltMutex.RUnlock() | ||||
| 		return b.salt, nil | ||||
| 	} | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	b.saltMutex.Lock() | ||||
| 	defer b.saltMutex.Unlock() | ||||
| 	if b.salt != nil { | ||||
| 		return b.salt, nil | ||||
| 	} | ||||
| 	salt, err := salt.NewSalt(b.view, &salt.Config{ | ||||
| 		HashFunc: salt.SHA256Hash, | ||||
| 		Location: salt.DefaultLocation, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	b.salt = salt | ||||
| 	return nil | ||||
| 	return salt, nil | ||||
| } | ||||
|  | ||||
| func (b *backend) invalidate(key string) { | ||||
| 	switch key { | ||||
| 	case salt.DefaultLocation: | ||||
| 		// reread the salt | ||||
| 		b.initialize() | ||||
| 		b.saltMutex.Lock() | ||||
| 		defer b.saltMutex.Unlock() | ||||
| 		b.salt = nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -21,9 +21,5 @@ func createBackendWithStorage(t *testing.T) (*backend, logical.Storage) { | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	err = b.Initialize() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	return b, config.StorageView | ||||
| } | ||||
|   | ||||
| @@ -1939,9 +1939,11 @@ func (b *backend) setRoleIDEntry(s logical.Storage, roleID string, roleIDEntry * | ||||
| 	lock.Lock() | ||||
| 	defer lock.Unlock() | ||||
|  | ||||
| 	b.saltMutex.RLock() | ||||
| 	entryIndex := "role_id/" + b.salt.SaltID(roleID) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	entryIndex := "role_id/" + salt.SaltID(roleID) | ||||
|  | ||||
| 	entry, err := logical.StorageEntryJSON(entryIndex, roleIDEntry) | ||||
| 	if err != nil { | ||||
| @@ -1965,9 +1967,11 @@ func (b *backend) roleIDEntry(s logical.Storage, roleID string) (*roleIDStorageE | ||||
|  | ||||
| 	var result roleIDStorageEntry | ||||
|  | ||||
| 	b.saltMutex.RLock() | ||||
| 	entryIndex := "role_id/" + b.salt.SaltID(roleID) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	entryIndex := "role_id/" + salt.SaltID(roleID) | ||||
|  | ||||
| 	if entry, err := s.Get(entryIndex); err != nil { | ||||
| 		return nil, err | ||||
| @@ -1991,9 +1995,11 @@ func (b *backend) roleIDEntryDelete(s logical.Storage, roleID string) error { | ||||
| 	lock.Lock() | ||||
| 	defer lock.Unlock() | ||||
|  | ||||
| 	b.saltMutex.RLock() | ||||
| 	entryIndex := "role_id/" + b.salt.SaltID(roleID) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	entryIndex := "role_id/" + salt.SaltID(roleID) | ||||
|  | ||||
| 	return s.Delete(entryIndex) | ||||
| } | ||||
|   | ||||
| @@ -469,9 +469,11 @@ func (b *backend) secretIDAccessorEntry(s logical.Storage, secretIDAccessor stri | ||||
| 	var result secretIDAccessorStorageEntry | ||||
|  | ||||
| 	// Create index entry, mapping the accessor to the token ID | ||||
| 	b.saltMutex.RLock() | ||||
| 	entryIndex := "accessor/" + b.salt.SaltID(secretIDAccessor) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	entryIndex := "accessor/" + salt.SaltID(secretIDAccessor) | ||||
|  | ||||
| 	accessorLock := b.secretIDAccessorLock(secretIDAccessor) | ||||
| 	accessorLock.RLock() | ||||
| @@ -500,9 +502,11 @@ func (b *backend) createSecretIDAccessorEntry(s logical.Storage, entry *secretID | ||||
| 	entry.SecretIDAccessor = accessorUUID | ||||
|  | ||||
| 	// Create index entry, mapping the accessor to the token ID | ||||
| 	b.saltMutex.RLock() | ||||
| 	entryIndex := "accessor/" + b.salt.SaltID(entry.SecretIDAccessor) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	entryIndex := "accessor/" + salt.SaltID(entry.SecretIDAccessor) | ||||
|  | ||||
| 	accessorLock := b.secretIDAccessorLock(accessorUUID) | ||||
| 	accessorLock.Lock() | ||||
| @@ -521,9 +525,11 @@ func (b *backend) createSecretIDAccessorEntry(s logical.Storage, entry *secretID | ||||
|  | ||||
| // deleteSecretIDAccessorEntry deletes the storage index mapping the accessor to a SecretID. | ||||
| func (b *backend) deleteSecretIDAccessorEntry(s logical.Storage, secretIDAccessor string) error { | ||||
| 	b.saltMutex.RLock() | ||||
| 	accessorEntryIndex := "accessor/" + b.salt.SaltID(secretIDAccessor) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	accessorEntryIndex := "accessor/" + salt.SaltID(secretIDAccessor) | ||||
|  | ||||
| 	accessorLock := b.secretIDAccessorLock(secretIDAccessor) | ||||
| 	accessorLock.Lock() | ||||
|   | ||||
| @@ -21,9 +21,6 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) { | ||||
| type backend struct { | ||||
| 	*framework.Backend | ||||
|  | ||||
| 	// Used during initialization to set the salt | ||||
| 	view logical.Storage | ||||
|  | ||||
| 	// Lock to make changes to any of the backend's configuration endpoints. | ||||
| 	configMutex sync.RWMutex | ||||
|  | ||||
| @@ -64,7 +61,6 @@ func Backend(conf *logical.BackendConfig) (*backend, error) { | ||||
| 		// Setting the periodic func to be run once in an hour. | ||||
| 		// If there is a real need, this can be made configurable. | ||||
| 		tidyCooldownPeriod: time.Hour, | ||||
| 		view:               conf.StorageView, | ||||
| 		EC2ClientsMap:      make(map[string]map[string]*ec2.EC2), | ||||
| 		IAMClientsMap:      make(map[string]map[string]*iam.IAM), | ||||
| 	} | ||||
|   | ||||
| @@ -17,10 +17,6 @@ func createBackendWithStorage(t *testing.T) (*backend, logical.Storage) { | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	err = b.Initialize() | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	return b, config.StorageView | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -59,32 +59,40 @@ func Backend(conf *logical.BackendConfig) (*backend, error) { | ||||
| 			secretOTP(&b), | ||||
| 		}, | ||||
|  | ||||
| 		Init: b.initialize, | ||||
|  | ||||
| 		Invalidate: b.invalidate, | ||||
| 	} | ||||
| 	return &b, nil | ||||
| } | ||||
|  | ||||
| func (b *backend) initialize() error { | ||||
| func (b *backend) Salt() (*salt.Salt, error) { | ||||
| 	b.saltMutex.RLock() | ||||
| 	if b.salt != nil { | ||||
| 		defer b.saltMutex.RUnlock() | ||||
| 		return b.salt, nil | ||||
| 	} | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	b.saltMutex.Lock() | ||||
| 	defer b.saltMutex.Unlock() | ||||
| 	if b.salt != nil { | ||||
| 		return b.salt, nil | ||||
| 	} | ||||
| 	salt, err := salt.NewSalt(b.view, &salt.Config{ | ||||
| 		HashFunc: salt.SHA256Hash, | ||||
| 		Location: salt.DefaultLocation, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	b.salt = salt | ||||
| 	return nil | ||||
| 	return salt, nil | ||||
| } | ||||
|  | ||||
| func (b *backend) invalidate(key string) { | ||||
| 	switch key { | ||||
| 	case salt.DefaultLocation: | ||||
| 		// reread the salt | ||||
| 		b.initialize() | ||||
| 		b.saltMutex.Lock() | ||||
| 		defer b.saltMutex.Unlock() | ||||
| 		b.salt = nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -207,9 +207,12 @@ func (b *backend) GenerateSaltedOTP() (string, string, error) { | ||||
| 	if err != nil { | ||||
| 		return "", "", err | ||||
| 	} | ||||
| 	b.saltMutex.RLock() | ||||
| 	defer b.saltMutex.RUnlock() | ||||
| 	return str, b.salt.SaltID(str), nil | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return "", "", err | ||||
| 	} | ||||
|  | ||||
| 	return str, salt.SaltID(str), nil | ||||
| } | ||||
|  | ||||
| // Generates an UUID OTP and creates an entry for the same in storage backend with its salted string. | ||||
|   | ||||
| @@ -57,9 +57,11 @@ func (b *backend) pathVerifyWrite(req *logical.Request, d *framework.FieldData) | ||||
| 	// Create the salt of OTP because entry would have been create with the | ||||
| 	// salt and not directly of the OTP. Salt will yield the same value which | ||||
| 	// because the seed is the same, the backend salt. | ||||
| 	b.saltMutex.RLock() | ||||
| 	otpSalted := b.salt.SaltID(otp) | ||||
| 	b.saltMutex.RUnlock() | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	otpSalted := salt.SaltID(otp) | ||||
|  | ||||
| 	// Return nil if there is no entry found for the OTP | ||||
| 	otpEntry, err := b.getOTP(req.Storage, otpSalted) | ||||
|   | ||||
| @@ -33,9 +33,11 @@ func (b *backend) secretOTPRevoke(req *logical.Request, d *framework.FieldData) | ||||
| 		return nil, fmt.Errorf("secret is missing internal data") | ||||
| 	} | ||||
|  | ||||
| 	b.saltMutex.RLock() | ||||
| 	defer b.saltMutex.RUnlock() | ||||
| 	err := req.Storage.Delete("otp/" + b.salt.SaltID(otp)) | ||||
| 	salt, err := b.Salt() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	err = req.Storage.Delete("otp/" + salt.SaltID(otp)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -21,7 +21,7 @@ type PathMap struct { | ||||
| 	Schema        map[string]*FieldSchema | ||||
| 	CaseSensitive bool | ||||
| 	Salt          *salt.Salt | ||||
| 	SaltMutex     *sync.RWMutex | ||||
| 	SaltFunc      func() (*salt.Salt, error) | ||||
|  | ||||
| 	once sync.Once | ||||
| } | ||||
| @@ -51,10 +51,12 @@ func (p *PathMap) pathStruct(k string) *PathStruct { | ||||
| 	} | ||||
|  | ||||
| 	// If we have a salt, apply it before lookup | ||||
| 	if p.Salt != nil { | ||||
| 		p.SaltMutex.RLock() | ||||
| 		k = p.Salt.SaltID(k) | ||||
| 		p.SaltMutex.RUnlock() | ||||
| 	salt := p.Salt | ||||
| 	if p.SaltFunc != nil { | ||||
| 		salt, _ = p.SaltFunc() | ||||
| 	} | ||||
| 	if salt != nil { | ||||
| 		k = salt.SaltID(k) | ||||
| 	} | ||||
|  | ||||
| 	return &PathStruct{ | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| package framework | ||||
|  | ||||
| import ( | ||||
| 	"sync" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/hashicorp/vault/helper/salt" | ||||
| @@ -140,14 +139,13 @@ func TestPathMap_routes(t *testing.T) { | ||||
|  | ||||
| func TestPathMap_Salted(t *testing.T) { | ||||
| 	storage := new(logical.InmemStorage) | ||||
| 	var mut sync.RWMutex | ||||
| 	salt, err := salt.NewSalt(storage, &salt.Config{ | ||||
| 		HashFunc: salt.SHA1Hash, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	p := &PathMap{Name: "foo", Salt: salt, SaltMutex: &mut} | ||||
| 	p := &PathMap{Name: "foo", Salt: salt} | ||||
| 	var b logical.Backend = &Backend{Paths: p.Paths()} | ||||
|  | ||||
| 	// Write via HTTP | ||||
| @@ -173,9 +171,129 @@ func TestPathMap_Salted(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Ensure the path is salted | ||||
| 	mut.RLock() | ||||
| 	expect := salt.SaltID("a") | ||||
| 	mut.RUnlock() | ||||
| 	out, err = storage.Get("struct/map/foo/" + expect) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	if out == nil { | ||||
| 		t.Fatalf("missing salted key") | ||||
| 	} | ||||
|  | ||||
| 	// Read via HTTP | ||||
| 	resp, err := b.HandleRequest(&logical.Request{ | ||||
| 		Operation: logical.ReadOperation, | ||||
| 		Path:      "map/foo/a", | ||||
| 		Storage:   storage, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if resp.Data["value"] != "bar" { | ||||
| 		t.Fatalf("bad: %#v", resp) | ||||
| 	} | ||||
|  | ||||
| 	// Read via API | ||||
| 	v, err := p.Get(storage, "a") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if v["value"] != "bar" { | ||||
| 		t.Fatalf("bad: %#v", v) | ||||
| 	} | ||||
|  | ||||
| 	// Read via API with other casing | ||||
| 	v, err = p.Get(storage, "A") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if v["value"] != "bar" { | ||||
| 		t.Fatalf("bad: %#v", v) | ||||
| 	} | ||||
|  | ||||
| 	// Verify List | ||||
| 	keys, err := p.List(storage, "") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if len(keys) != 1 || keys[0] != expect { | ||||
| 		t.Fatalf("bad: %#v", keys) | ||||
| 	} | ||||
|  | ||||
| 	// Delete via HTTP | ||||
| 	resp, err = b.HandleRequest(&logical.Request{ | ||||
| 		Operation: logical.DeleteOperation, | ||||
| 		Path:      "map/foo/a", | ||||
| 		Storage:   storage, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if resp != nil { | ||||
| 		t.Fatalf("bad: %#v", resp) | ||||
| 	} | ||||
|  | ||||
| 	// Re-read via HTTP | ||||
| 	resp, err = b.HandleRequest(&logical.Request{ | ||||
| 		Operation: logical.ReadOperation, | ||||
| 		Path:      "map/foo/a", | ||||
| 		Storage:   storage, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if _, ok := resp.Data["value"]; ok { | ||||
| 		t.Fatalf("bad: %#v", resp) | ||||
| 	} | ||||
|  | ||||
| 	// Re-read via API | ||||
| 	v, err = p.Get(storage, "a") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
| 	if v != nil { | ||||
| 		t.Fatalf("bad: %#v", v) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func TestPathMap_SaltFunc(t *testing.T) { | ||||
| 	storage := new(logical.InmemStorage) | ||||
| 	locSalt, err := salt.NewSalt(storage, &salt.Config{ | ||||
| 		HashFunc: salt.SHA1Hash, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	saltFunc := func() (*salt.Salt, error) { | ||||
| 		return locSalt, nil | ||||
| 	} | ||||
| 	p := &PathMap{Name: "foo", SaltFunc: saltFunc} | ||||
| 	var b logical.Backend = &Backend{Paths: p.Paths()} | ||||
|  | ||||
| 	// Write via HTTP | ||||
| 	_, err = b.HandleRequest(&logical.Request{ | ||||
| 		Operation: logical.UpdateOperation, | ||||
| 		Path:      "map/foo/a", | ||||
| 		Data: map[string]interface{}{ | ||||
| 			"value": "bar", | ||||
| 		}, | ||||
| 		Storage: storage, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("bad: %#v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Non-salted version should not be there | ||||
| 	out, err := storage.Get("struct/map/foo/a") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| 	if out != nil { | ||||
| 		t.Fatalf("non-salted key found") | ||||
| 	} | ||||
|  | ||||
| 	// Ensure the path is salted | ||||
| 	expect := locSalt.SaltID("a") | ||||
| 	out, err = storage.Get("struct/map/foo/" + expect) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
|   | ||||
| @@ -42,7 +42,7 @@ var ( | ||||
| ) | ||||
|  | ||||
| // enableCredential is used to enable a new credential backend | ||||
| func (c *Core) enableCredential(entry *MountEntry, skipInitialization bool) error { | ||||
| func (c *Core) enableCredential(entry *MountEntry) error { | ||||
| 	// Ensure we end the path in a slash | ||||
| 	if !strings.HasSuffix(entry.Path, "/") { | ||||
| 		entry.Path += "/" | ||||
| @@ -99,10 +99,8 @@ func (c *Core) enableCredential(entry *MountEntry, skipInitialization bool) erro | ||||
| 		return fmt.Errorf("nil backend returned from %q factory", entry.Type) | ||||
| 	} | ||||
|  | ||||
| 	if !skipInitialization { | ||||
| 		if err := backend.Initialize(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	if err := backend.Initialize(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Update the auth table | ||||
|   | ||||
| @@ -49,7 +49,7 @@ func TestCore_EnableCredential(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	err := c.enableCredential(me, false) | ||||
| 	err := c.enableCredential(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -179,13 +179,13 @@ func TestCore_EnableCredential_twice_409(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	err := c.enableCredential(me, false) | ||||
| 	err := c.enableCredential(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// 2nd should be a 409 error | ||||
| 	err2 := c.enableCredential(me, false) | ||||
| 	err2 := c.enableCredential(me) | ||||
| 	switch err2.(type) { | ||||
| 	case logical.HTTPCodedError: | ||||
| 		if err2.(logical.HTTPCodedError).Code() != 409 { | ||||
| @@ -203,7 +203,7 @@ func TestCore_EnableCredential_Token(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "token", | ||||
| 	} | ||||
| 	err := c.enableCredential(me, false) | ||||
| 	err := c.enableCredential(me) | ||||
| 	if err.Error() != "token credential backend cannot be instantiated" { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -225,7 +225,7 @@ func TestCore_DisableCredential(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	err = c.enableCredential(me, false) | ||||
| 	err = c.enableCredential(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -286,7 +286,7 @@ func TestCore_DisableCredential_Cleanup(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	err := c.enableCredential(me, false) | ||||
| 	err := c.enableCredential(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|   | ||||
| @@ -1352,7 +1352,7 @@ func TestExpiration_RevokeForce(t *testing.T) { | ||||
| 		Type:  "badrenew", | ||||
| 	} | ||||
|  | ||||
| 	err := core.mount(me, false) | ||||
| 	err := core.mount(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|   | ||||
| @@ -1210,7 +1210,7 @@ func (b *SystemBackend) handleMount( | ||||
| 	} | ||||
|  | ||||
| 	// Attempt mount | ||||
| 	if err := b.Core.mount(me, false); err != nil { | ||||
| 	if err := b.Core.mount(me); err != nil { | ||||
| 		b.Backend.Logger().Error("sys: mount failed", "path", me.Path, "error", err) | ||||
| 		return handleError(err) | ||||
| 	} | ||||
| @@ -1642,7 +1642,7 @@ func (b *SystemBackend) handleEnableAuth( | ||||
| 	} | ||||
|  | ||||
| 	// Attempt enabling | ||||
| 	if err := b.Core.enableCredential(me, false); err != nil { | ||||
| 	if err := b.Core.enableCredential(me); err != nil { | ||||
| 		b.Backend.Logger().Error("sys: enable auth mount failed", "path", me.Path, "error", err) | ||||
| 		return handleError(err) | ||||
| 	} | ||||
|   | ||||
| @@ -172,7 +172,7 @@ func (e *MountEntry) Clone() *MountEntry { | ||||
| } | ||||
|  | ||||
| // Mount is used to mount a new backend to the mount table. | ||||
| func (c *Core) mount(entry *MountEntry, skipInitialization bool) error { | ||||
| func (c *Core) mount(entry *MountEntry) error { | ||||
| 	// Ensure we end the path in a slash | ||||
| 	if !strings.HasSuffix(entry.Path, "/") { | ||||
| 		entry.Path += "/" | ||||
| @@ -222,10 +222,8 @@ func (c *Core) mount(entry *MountEntry, skipInitialization bool) error { | ||||
|  | ||||
| 	// Call initialize; this takes care of init tasks that must be run after | ||||
| 	// the ignore paths are collected | ||||
| 	if !skipInitialization { | ||||
| 		if err := backend.Initialize(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	if err := backend.Initialize(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	newTable := c.mounts.shallowClone() | ||||
|   | ||||
| @@ -49,7 +49,7 @@ func TestCore_Mount(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "generic", | ||||
| 	} | ||||
| 	err := c.mount(me, false) | ||||
| 	err := c.mount(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -226,7 +226,7 @@ func TestCore_Unmount_Cleanup(t *testing.T) { | ||||
| 		Path:  "test/", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	if err := c.mount(me, false); err != nil { | ||||
| 	if err := c.mount(me); err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| @@ -346,7 +346,7 @@ func TestCore_Remount_Cleanup(t *testing.T) { | ||||
| 		Path:  "test/", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	if err := c.mount(me, false); err != nil { | ||||
| 	if err := c.mount(me); err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| @@ -458,7 +458,7 @@ func TestCore_MountTable_UpgradeToTyped(t *testing.T) { | ||||
| 		Path:  "foo", | ||||
| 		Type:  "noop", | ||||
| 	} | ||||
| 	err = c.enableCredential(me, false) | ||||
| 	err = c.enableCredential(me) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|   | ||||
| @@ -20,7 +20,7 @@ func TestRequestHandling_Wrapping(t *testing.T) { | ||||
| 		UUID:  meUUID, | ||||
| 		Path:  "wraptest", | ||||
| 		Type:  "generic", | ||||
| 	}, false) | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|   | ||||
| @@ -134,7 +134,7 @@ func NewTokenStore(c *Core, config *logical.BackendConfig) (*TokenStore, error) | ||||
| 				lookupPrefix, | ||||
| 				accessorPrefix, | ||||
| 				parentPrefix, | ||||
| 				"salt", | ||||
| 				salt.DefaultLocation, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| @@ -480,6 +480,7 @@ func (ts *TokenStore) Initialize() error { | ||||
| 	// Setup the salt | ||||
| 	salt, err := salt.NewSalt(ts.view, &salt.Config{ | ||||
| 		HashFunc: salt.SHA1Hash, | ||||
| 		Location: salt.DefaultLocation, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jeff Mitchell
					Jeff Mitchell