mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-12-08 11:53:16 +01:00
cmd/commands: add root_key flag to bakemacaroon command
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/lightningnetwork/lnd/fn"
|
||||||
"github.com/lightningnetwork/lnd/lncfg"
|
"github.com/lightningnetwork/lnd/lncfg"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/macaroons"
|
"github.com/lightningnetwork/lnd/macaroons"
|
||||||
@@ -38,6 +39,12 @@ var (
|
|||||||
Usage: "the condition of the custom caveat to add, can be " +
|
Usage: "the condition of the custom caveat to add, can be " +
|
||||||
"empty if custom caveat doesn't need a value",
|
"empty if custom caveat doesn't need a value",
|
||||||
}
|
}
|
||||||
|
bakeFromRootKeyFlag = cli.StringFlag{
|
||||||
|
Name: "root_key",
|
||||||
|
Usage: "if the root key is known, it can be passed directly " +
|
||||||
|
"as a hex encoded string, turning the command into " +
|
||||||
|
"an offline operation",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var bakeMacaroonCommand = cli.Command{
|
var bakeMacaroonCommand = cli.Command{
|
||||||
@@ -48,7 +55,7 @@ var bakeMacaroonCommand = cli.Command{
|
|||||||
ArgsUsage: "[--save_to=] [--timeout=] [--ip_address=] " +
|
ArgsUsage: "[--save_to=] [--timeout=] [--ip_address=] " +
|
||||||
"[--custom_caveat_name= [--custom_caveat_condition=]] " +
|
"[--custom_caveat_name= [--custom_caveat_condition=]] " +
|
||||||
"[--root_key_id=] [--allow_external_permissions] " +
|
"[--root_key_id=] [--allow_external_permissions] " +
|
||||||
"permissions...",
|
"[--root_key=] permissions...",
|
||||||
Description: `
|
Description: `
|
||||||
Bake a new macaroon that grants the provided permissions and
|
Bake a new macaroon that grants the provided permissions and
|
||||||
optionally adds restrictions (timeout, IP address) to it.
|
optionally adds restrictions (timeout, IP address) to it.
|
||||||
@@ -74,6 +81,12 @@ var bakeMacaroonCommand = cli.Command{
|
|||||||
|
|
||||||
To get a list of all available URIs and permissions, use the
|
To get a list of all available URIs and permissions, use the
|
||||||
"lncli listpermissions" command.
|
"lncli listpermissions" command.
|
||||||
|
|
||||||
|
If the root key is known (for example because "lncli create" was used
|
||||||
|
with a custom --mac_root_key value), it can be passed directly as a
|
||||||
|
hex encoded string using the --root_key flag. This turns the command
|
||||||
|
into an offline operation and the macaroon will be created without
|
||||||
|
calling into the server's RPC endpoint.
|
||||||
`,
|
`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
@@ -95,14 +108,13 @@ var bakeMacaroonCommand = cli.Command{
|
|||||||
Usage: "whether permissions lnd is not familiar with " +
|
Usage: "whether permissions lnd is not familiar with " +
|
||||||
"are allowed",
|
"are allowed",
|
||||||
},
|
},
|
||||||
|
bakeFromRootKeyFlag,
|
||||||
},
|
},
|
||||||
Action: actionDecorator(bakeMacaroon),
|
Action: actionDecorator(bakeMacaroon),
|
||||||
}
|
}
|
||||||
|
|
||||||
func bakeMacaroon(ctx *cli.Context) error {
|
func bakeMacaroon(ctx *cli.Context) error {
|
||||||
ctxc := getContext()
|
ctxc := getContext()
|
||||||
client, cleanUp := getClient(ctx)
|
|
||||||
defer cleanUp()
|
|
||||||
|
|
||||||
// Show command help if no arguments.
|
// Show command help if no arguments.
|
||||||
if ctx.NArg() == 0 {
|
if ctx.NArg() == 0 {
|
||||||
@@ -154,36 +166,66 @@ func bakeMacaroon(ctx *cli.Context) error {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we have gathered all the input we need and can do the actual
|
var rawMacaroon *macaroon.Macaroon
|
||||||
// RPC call.
|
switch {
|
||||||
req := &lnrpc.BakeMacaroonRequest{
|
case ctx.IsSet(bakeFromRootKeyFlag.Name):
|
||||||
Permissions: parsedPermissions,
|
macRootKey, err := hex.DecodeString(
|
||||||
RootKeyId: rootKeyID,
|
ctx.String(bakeFromRootKeyFlag.Name),
|
||||||
AllowExternalPermissions: ctx.Bool("allow_external_permissions"),
|
)
|
||||||
}
|
if err != nil {
|
||||||
resp, err := client.BakeMacaroon(ctxc, req)
|
return fmt.Errorf("unable to parse macaroon root key: "+
|
||||||
if err != nil {
|
"%w", err)
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Now we should have gotten a valid macaroon. Unmarshal it so we can
|
ops := fn.Map(func(p *lnrpc.MacaroonPermission) bakery.Op {
|
||||||
// add first-party caveats (if necessary) to it.
|
return bakery.Op{
|
||||||
macBytes, err := hex.DecodeString(resp.Macaroon)
|
Entity: p.Entity,
|
||||||
if err != nil {
|
Action: p.Action,
|
||||||
return err
|
}
|
||||||
}
|
}, parsedPermissions)
|
||||||
unmarshalMac := &macaroon.Macaroon{}
|
|
||||||
if err = unmarshalMac.UnmarshalBinary(macBytes); err != nil {
|
rawMacaroon, err = macaroons.BakeFromRootKey(macRootKey, ops)
|
||||||
return err
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to bake macaroon: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
client, cleanUp := getClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
// Now we have gathered all the input we need and can do the
|
||||||
|
// actual RPC call.
|
||||||
|
req := &lnrpc.BakeMacaroonRequest{
|
||||||
|
Permissions: parsedPermissions,
|
||||||
|
RootKeyId: rootKeyID,
|
||||||
|
AllowExternalPermissions: ctx.Bool(
|
||||||
|
"allow_external_permissions",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
resp, err := client.BakeMacaroon(ctxc, req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we should have gotten a valid macaroon. Unmarshal it so
|
||||||
|
// we can add first-party caveats (if necessary) to it.
|
||||||
|
macBytes, err := hex.DecodeString(resp.Macaroon)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rawMacaroon = &macaroon.Macaroon{}
|
||||||
|
if err = rawMacaroon.UnmarshalBinary(macBytes); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now apply the desired constraints to the macaroon. This will always
|
// Now apply the desired constraints to the macaroon. This will always
|
||||||
// create a new macaroon object, even if no constraints are added.
|
// create a new macaroon object, even if no constraints are added.
|
||||||
constrainedMac, err := applyMacaroonConstraints(ctx, unmarshalMac)
|
constrainedMac, err := applyMacaroonConstraints(ctx, rawMacaroon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
macBytes, err = constrainedMac.MarshalBinary()
|
macBytes, err := constrainedMac.MarshalBinary()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user