multi: upgrade macaroons to v2, replace per-method auth with interceptors

This commit reworks the macaroon authentication framework to use the
v2 macaroon format and bakery API. It also replaces the code in each
RPC method which calls the macaroon verifier with interceptors which
call the macaroon verifier instead. In addition, the operation
permissions are reworked to fit the new format of "allow" commands
(specifically, entity/operation permissions instead of method
permissions).
This commit is contained in:
Alex authored and Olaoluwa Osuntokun committed 2018-01-31 17:14:49 -08:00
1 parent 20098e8cb3
commit 21c29c33d7
11 files changed
+427 -514

No files matched your search

+11 -29
View File
@@ -3,15 +3,13 @@ package macaroons
import (
"encoding/hex"
"fmt"
"net"
"google.golang.org/grpc/metadata"
"golang.org/x/net/context"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer"
"gopkg.in/macaroon-bakery.v1/bakery"
"gopkg.in/macaroon-bakery.v1/bakery/checkers"
macaroon "gopkg.in/macaroon.v1"
"gopkg.in/macaroon-bakery.v2/bakery"
macaroon "gopkg.in/macaroon.v2"
)
// MacaroonCredential wraps a macaroon to implement the
@@ -54,13 +52,11 @@ func NewMacaroonCredential(m *macaroon.Macaroon) MacaroonCredential {
// bakery service, context, and uri. Within the passed context.Context, we
// expect a macaroon to be encoded as request metadata using the key
// "macaroon".
func ValidateMacaroon(ctx context.Context, method string,
svc *bakery.Service) error {
func ValidateMacaroon(ctx context.Context, requiredPermissions []bakery.Op,
svc *bakery.Bakery) error {
// Get macaroon bytes from context and unmarshal into macaroon.
//
// TODO(aakselrod): use FromIncomingContext after grpc update in glide.
md, ok := metadata.FromContext(ctx)
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return fmt.Errorf("unable to get metadata from context")
}
@@ -69,16 +65,6 @@ func ValidateMacaroon(ctx context.Context, method string,
len(md["macaroon"]))
}
// Get peer info and extract IP address from it for macaroon check
pr, ok := peer.FromContext(ctx)
if !ok {
return fmt.Errorf("unable to get peer info from context")
}
peerAddr, _, err := net.SplitHostPort(pr.Addr.String())
if err != nil {
return fmt.Errorf("unable to parse peer address")
}
// With the macaroon obtained, we'll now decode the hex-string
// encoding, then unmarshal it from binary into its concrete struct
// representation.
@@ -93,12 +79,8 @@ func ValidateMacaroon(ctx context.Context, method string,
}
// Check the method being called against the permitted operation and
// the expiration time and return the result.
//
// TODO(aakselrod): Add more checks as required.
return svc.Check(macaroon.Slice{mac}, checkers.New(
AllowChecker(method),
TimeoutChecker(),
IPLockChecker(peerAddr),
))
// the expiration time and IP address and return the result.
authChecker := svc.Checker.Auth(macaroon.Slice{mac})
_, err = authChecker.Allow(ctx, requiredPermissions...)
return err
}