mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-13 11:09:23 +01:00
cmd/commands: add root_key flag to bakemacaroon command
This commit is contained in:
parent
6e932c6bc8
commit
882f25667e
1 changed files with 67 additions and 25 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/lightningnetwork/lnd/fn"
|
||||
"github.com/lightningnetwork/lnd/lncfg"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/macaroons"
|
||||
|
@ -38,6 +39,12 @@ var (
|
|||
Usage: "the condition of the custom caveat to add, can be " +
|
||||
"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{
|
||||
|
@ -48,7 +55,7 @@ var bakeMacaroonCommand = cli.Command{
|
|||
ArgsUsage: "[--save_to=] [--timeout=] [--ip_address=] " +
|
||||
"[--custom_caveat_name= [--custom_caveat_condition=]] " +
|
||||
"[--root_key_id=] [--allow_external_permissions] " +
|
||||
"permissions...",
|
||||
"[--root_key=] permissions...",
|
||||
Description: `
|
||||
Bake a new macaroon that grants the provided permissions and
|
||||
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
|
||||
"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{
|
||||
cli.StringFlag{
|
||||
|
@ -95,14 +108,13 @@ var bakeMacaroonCommand = cli.Command{
|
|||
Usage: "whether permissions lnd is not familiar with " +
|
||||
"are allowed",
|
||||
},
|
||||
bakeFromRootKeyFlag,
|
||||
},
|
||||
Action: actionDecorator(bakeMacaroon),
|
||||
}
|
||||
|
||||
func bakeMacaroon(ctx *cli.Context) error {
|
||||
ctxc := getContext()
|
||||
client, cleanUp := getClient(ctx)
|
||||
defer cleanUp()
|
||||
|
||||
// Show command help if no arguments.
|
||||
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
|
||||
// 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
|
||||
}
|
||||
var rawMacaroon *macaroon.Macaroon
|
||||
switch {
|
||||
case ctx.IsSet(bakeFromRootKeyFlag.Name):
|
||||
macRootKey, err := hex.DecodeString(
|
||||
ctx.String(bakeFromRootKeyFlag.Name),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse macaroon root key: "+
|
||||
"%w", 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
|
||||
}
|
||||
unmarshalMac := &macaroon.Macaroon{}
|
||||
if err = unmarshalMac.UnmarshalBinary(macBytes); err != nil {
|
||||
return err
|
||||
ops := fn.Map(func(p *lnrpc.MacaroonPermission) bakery.Op {
|
||||
return bakery.Op{
|
||||
Entity: p.Entity,
|
||||
Action: p.Action,
|
||||
}
|
||||
}, parsedPermissions)
|
||||
|
||||
rawMacaroon, err = macaroons.BakeFromRootKey(macRootKey, ops)
|
||||
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
|
||||
// create a new macaroon object, even if no constraints are added.
|
||||
constrainedMac, err := applyMacaroonConstraints(ctx, unmarshalMac)
|
||||
constrainedMac, err := applyMacaroonConstraints(ctx, rawMacaroon)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
macBytes, err = constrainedMac.MarshalBinary()
|
||||
macBytes, err := constrainedMac.MarshalBinary()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue