mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-21 06:12:38 +02:00
lnrpc+lncli: add command to print macaroon
This commit is contained in:
parent
3ce7f72cd4
commit
4996b28dab
@ -10,9 +10,11 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/proto"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/macaroons"
|
"github.com/lightningnetwork/lnd/macaroons"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
|
"gopkg.in/macaroon-bakery.v2/bakery"
|
||||||
"gopkg.in/macaroon.v2"
|
"gopkg.in/macaroon.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -305,3 +307,102 @@ func listPermissions(ctx *cli.Context) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type macaroonContent struct {
|
||||||
|
Version uint16 `json:"version"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
RootKeyID string `json:"root_key_id"`
|
||||||
|
Permissions []string `json:"permissions"`
|
||||||
|
Caveats []string `json:"caveats"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var printMacaroonCommand = cli.Command{
|
||||||
|
Name: "printmacaroon",
|
||||||
|
Category: "Macaroons",
|
||||||
|
Usage: "Print the content of a macaroon in a human readable format.",
|
||||||
|
ArgsUsage: "[macaroon_content_hex]",
|
||||||
|
Description: `
|
||||||
|
Decode a macaroon and show its content in a more human readable format.
|
||||||
|
The macaroon can either be passed as a hex encoded positional parameter
|
||||||
|
or loaded from a file.
|
||||||
|
`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "macaroon_file",
|
||||||
|
Usage: "load the macaroon from a file instead of the " +
|
||||||
|
"command line directly",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(printMacaroon),
|
||||||
|
}
|
||||||
|
|
||||||
|
func printMacaroon(ctx *cli.Context) error {
|
||||||
|
// Show command help if no arguments or flags are set.
|
||||||
|
if ctx.NArg() == 0 && ctx.NumFlags() == 0 {
|
||||||
|
return cli.ShowCommandHelp(ctx, "printmacaroon")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
macBytes []byte
|
||||||
|
err error
|
||||||
|
args = ctx.Args()
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("macaroon_file"):
|
||||||
|
macPath := cleanAndExpandPath(ctx.String("macaroon_file"))
|
||||||
|
|
||||||
|
// Load the specified macaroon file.
|
||||||
|
macBytes, err = ioutil.ReadFile(macPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read macaroon path %v: %v",
|
||||||
|
macPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
case args.Present():
|
||||||
|
macBytes, err = hex.DecodeString(args.First())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to hex decode macaroon: %v",
|
||||||
|
err)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("macaroon parameter missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode the macaroon and its protobuf encoded internal identifier.
|
||||||
|
mac := &macaroon.Macaroon{}
|
||||||
|
if err = mac.UnmarshalBinary(macBytes); err != nil {
|
||||||
|
return fmt.Errorf("unable to decode macaroon: %v", err)
|
||||||
|
}
|
||||||
|
rawID := mac.Id()
|
||||||
|
if rawID[0] != byte(bakery.LatestVersion) {
|
||||||
|
return fmt.Errorf("invalid macaroon version: %x", rawID)
|
||||||
|
}
|
||||||
|
decodedID := &lnrpc.MacaroonId{}
|
||||||
|
idProto := rawID[1:]
|
||||||
|
err = proto.Unmarshal(idProto, decodedID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to decode macaroon version: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare everything to be printed in a more human readable format.
|
||||||
|
content := &macaroonContent{
|
||||||
|
Version: uint16(mac.Version()),
|
||||||
|
Location: mac.Location(),
|
||||||
|
RootKeyID: string(decodedID.StorageId),
|
||||||
|
Permissions: nil,
|
||||||
|
Caveats: nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, caveat := range mac.Caveats() {
|
||||||
|
content.Caveats = append(content.Caveats, string(caveat.Id))
|
||||||
|
}
|
||||||
|
for _, op := range decodedID.Ops {
|
||||||
|
permission := fmt.Sprintf("%s:%s", op.Entity, op.Actions[0])
|
||||||
|
content.Permissions = append(content.Permissions, permission)
|
||||||
|
}
|
||||||
|
|
||||||
|
printJSON(content)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -304,6 +304,7 @@ func main() {
|
|||||||
listMacaroonIDsCommand,
|
listMacaroonIDsCommand,
|
||||||
deleteMacaroonIDCommand,
|
deleteMacaroonIDCommand,
|
||||||
listPermissionsCommand,
|
listPermissionsCommand,
|
||||||
|
printMacaroonCommand,
|
||||||
trackPaymentCommand,
|
trackPaymentCommand,
|
||||||
versionCommand,
|
versionCommand,
|
||||||
}
|
}
|
||||||
|
1595
lnrpc/rpc.pb.go
1595
lnrpc/rpc.pb.go
File diff suppressed because it is too large
Load Diff
@ -3559,3 +3559,14 @@ message ChannelUpdate {
|
|||||||
*/
|
*/
|
||||||
bytes extra_opaque_data = 12;
|
bytes extra_opaque_data = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message MacaroonId {
|
||||||
|
bytes nonce = 1;
|
||||||
|
bytes storageId = 2;
|
||||||
|
repeated Op ops = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Op {
|
||||||
|
string entity = 1;
|
||||||
|
repeated string actions = 2;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user