macaroons: reject unknown macaroon versions

We've only ever made macaroons with the v2 versions, so we should
explicitly reject those that aren't actually v2. We add a basic test
along the way, and also add a similar check for the version encoded in
the macaroon ID.
This commit is contained in:
Olaoluwa Osuntokun committed 2023-10-31 13:23:50 -07:00
1 parent c382268201
commit 9287b755d8
5 files changed
+110 -2

No files matched your search

+72
View File
@@ -12,6 +12,7 @@ import (
"google.golang.org/grpc/metadata"
"gopkg.in/macaroon-bakery.v2/bakery"
"gopkg.in/macaroon-bakery.v2/bakery/checkers"
macaroon "gopkg.in/macaroon.v2"
)
var (
@@ -53,6 +54,8 @@ func setupTestRootKeyStorage(t *testing.T) kvdb.Backend {
// TestNewService tests the creation of the macaroon service.
func TestNewService(t *testing.T) {
t.Parallel()
// First, initialize a dummy DB file with a store that the service
// can read from. Make sure the file is removed in the end.
db := setupTestRootKeyStorage(t)
@@ -104,6 +107,8 @@ func TestNewService(t *testing.T) {
// TestValidateMacaroon tests the validation of a macaroon that is in an
// incoming context.
func TestValidateMacaroon(t *testing.T) {
t.Parallel()
// First, initialize the service and unlock it.
db := setupTestRootKeyStorage(t)
rootKeyStore, err := macaroons.NewRootKeyStorage(db)
@@ -149,6 +154,8 @@ func TestValidateMacaroon(t *testing.T) {
// TestListMacaroonIDs checks that ListMacaroonIDs returns the expected result.
func TestListMacaroonIDs(t *testing.T) {
t.Parallel()
// First, initialize a dummy DB file with a store that the service
// can read from. Make sure the file is removed in the end.
db := setupTestRootKeyStorage(t)
@@ -180,6 +187,8 @@ func TestListMacaroonIDs(t *testing.T) {
// TestDeleteMacaroonID removes the specific root key ID.
func TestDeleteMacaroonID(t *testing.T) {
t.Parallel()
ctxb := context.Background()
// First, initialize a dummy DB file with a store that the service
@@ -237,6 +246,8 @@ func TestDeleteMacaroonID(t *testing.T) {
// TestCloneMacaroons tests that macaroons can be cloned correctly and that
// modifications to the copy don't affect the original.
func TestCloneMacaroons(t *testing.T) {
t.Parallel()
// Get a configured version of the constraint function.
constraintFunc := macaroons.TimeoutConstraint(3)
@@ -288,3 +299,64 @@ func TestCloneMacaroons(t *testing.T) {
newMac.Caveats()[0].Location,
)
}
// TestMacaroonVersionDecode tests that we'll reject macaroons with an unknown
// version.
func TestMacaroonVersionDecode(t *testing.T) {
t.Parallel()
ctxb := context.Background()
// First, initialize a dummy DB file with a store that the service
// can read from. Make sure the file is removed in the end.
db := setupTestRootKeyStorage(t)
// Second, create the new service instance, unlock it and pass in a
// checker that we expect it to add to the bakery.
rootKeyStore, err := macaroons.NewRootKeyStorage(db)
require.NoError(t, err)
service, err := macaroons.NewService(
rootKeyStore, "lnd", false, macaroons.IPLockChecker,
)
require.NoError(t, err, "Error creating new service")
defer service.Close()
t.Run("invalid_version", func(t *testing.T) {
// Now that we have our sample service, we'll make a new custom
// macaroon with an unknown version.
testMac, err := macaroon.New(
testRootKey, testID, testLocation, 1,
)
require.NoError(t, err)
// Next, we'll serialize the macaroon to the binary form,
// modifying the first byte to signal an unknown version.
testMacBytes, err := testMac.MarshalBinary()
require.NoError(t, err)
// If we attempt to check the mac auth, then we should get a
// failure that the version is unknown.
err = service.CheckMacAuth(ctxb, testMacBytes, nil, "")
require.ErrorIs(t, err, macaroons.ErrUnknownVersion)
})
t.Run("invalid_id", func(t *testing.T) {
// We'll now make a macaroon with a valid version, but modify
// the ID to be rejected.
badID := []byte{}
testMac, err := macaroon.New(
testRootKey, badID, testLocation, testVersion,
)
require.NoError(t, err)
testMacBytes, err := testMac.MarshalBinary()
require.NoError(t, err)
// If we attempt to check the mac auth, then we should get a
// failure that the ID is bad.
err = service.CheckMacAuth(ctxb, testMacBytes, nil, "")
require.ErrorIs(t, err, macaroons.ErrInvalidID)
})
}