lncli: add custom caveats to bakemacaroon
With the new condition and checker in place, we can give the end user the ability to add such a custom caveat to a baked macaroon. There won't be an RPC counterpart for this operation since all first party caveats currently are only added on the client side.
This commit is contained in:
1 file changed
+57
@@ -8,6 +8,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"unicode"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/lightningnetwork/lnd/lncfg"
|
"github.com/lightningnetwork/lnd/lncfg"
|
||||||
@@ -65,6 +66,16 @@ var bakeMacaroonCommand = cli.Command{
|
|||||||
Name: "ip_address",
|
Name: "ip_address",
|
||||||
Usage: "the IP address the macaroon will be bound to",
|
Usage: "the IP address the macaroon will be bound to",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "custom_caveat_name",
|
||||||
|
Usage: "the name of the custom caveat to add",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "custom_caveat_condition",
|
||||||
|
Usage: "the condition of the custom caveat to add, " +
|
||||||
|
"can be empty if custom caveat doesn't need " +
|
||||||
|
"a value",
|
||||||
|
},
|
||||||
cli.Uint64Flag{
|
cli.Uint64Flag{
|
||||||
Name: "root_key_id",
|
Name: "root_key_id",
|
||||||
Usage: "the numerical root key ID used to create the macaroon",
|
Usage: "the numerical root key ID used to create the macaroon",
|
||||||
@@ -92,6 +103,8 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
savePath string
|
savePath string
|
||||||
timeout int64
|
timeout int64
|
||||||
ipAddress net.IP
|
ipAddress net.IP
|
||||||
|
customCaveatName string
|
||||||
|
customCaveatCond string
|
||||||
rootKeyID uint64
|
rootKeyID uint64
|
||||||
parsedPermissions []*lnrpc.MacaroonPermission
|
parsedPermissions []*lnrpc.MacaroonPermission
|
||||||
err error
|
err error
|
||||||
@@ -116,6 +129,32 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.IsSet("custom_caveat_name") {
|
||||||
|
customCaveatName = ctx.String("custom_caveat_name")
|
||||||
|
if containsWhiteSpace(customCaveatName) {
|
||||||
|
return fmt.Errorf("unexpected white space found in " +
|
||||||
|
"custom caveat name")
|
||||||
|
}
|
||||||
|
if customCaveatName == "" {
|
||||||
|
return fmt.Errorf("invalid custom caveat name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.IsSet("custom_caveat_condition") {
|
||||||
|
customCaveatCond = ctx.String("custom_caveat_condition")
|
||||||
|
if containsWhiteSpace(customCaveatCond) {
|
||||||
|
return fmt.Errorf("unexpected white space found in " +
|
||||||
|
"custom caveat condition")
|
||||||
|
}
|
||||||
|
if customCaveatCond == "" {
|
||||||
|
return fmt.Errorf("invalid custom caveat condition")
|
||||||
|
}
|
||||||
|
if customCaveatCond != "" && customCaveatName == "" {
|
||||||
|
return fmt.Errorf("cannot set custom caveat " +
|
||||||
|
"condition without custom caveat name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ctx.IsSet("root_key_id") {
|
if ctx.IsSet("root_key_id") {
|
||||||
rootKeyID = ctx.Uint64("root_key_id")
|
rootKeyID = ctx.Uint64("root_key_id")
|
||||||
}
|
}
|
||||||
@@ -186,6 +225,17 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
macaroons.IPLockConstraint(ipAddress.String()),
|
macaroons.IPLockConstraint(ipAddress.String()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The custom caveat condition is optional, it could just be a marker
|
||||||
|
// tag in the macaroon with just a name. The interceptor itself doesn't
|
||||||
|
// care about the value anyway.
|
||||||
|
if customCaveatName != "" {
|
||||||
|
macConstraints = append(
|
||||||
|
macConstraints, macaroons.CustomConstraint(
|
||||||
|
customCaveatName, customCaveatCond,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
constrainedMac, err := macaroons.AddConstraints(
|
constrainedMac, err := macaroons.AddConstraints(
|
||||||
unmarshalMac, macConstraints...,
|
unmarshalMac, macConstraints...,
|
||||||
)
|
)
|
||||||
@@ -419,3 +469,10 @@ func printMacaroon(ctx *cli.Context) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// containsWhiteSpace returns true if the given string contains any character
|
||||||
|
// that is considered to be a white space or non-printable character such as
|
||||||
|
// space, tabulator, newline, carriage return and some more exotic ones.
|
||||||
|
func containsWhiteSpace(str string) bool {
|
||||||
|
return strings.IndexFunc(str, unicode.IsSpace) >= 0
|
||||||
|
}
|
||||||
Reference in new issue
Block a user