Skip to content

Commit d3358ef

Browse files
authored
Merge pull request #292 from ellemouton/adminSuperMac
multi: readonly and admin macaroon session
2 parents 5cf26cb + 8b9ec31 commit d3358ef

File tree

11 files changed

+928
-135
lines changed

11 files changed

+928
-135
lines changed

cmd/litcli/sessions.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ var addSessionCommand = cli.Command{
5050
Usage: "set to true to skip verification of the " +
5151
"server's tls cert.",
5252
},
53+
cli.StringFlag{
54+
Name: "type",
55+
Usage: "session type to be created which will " +
56+
"determine the permissions a user has when " +
57+
"connecting with the session. Options " +
58+
"include readonly|admin",
59+
Value: "readonly",
60+
},
5361
},
5462
}
5563

@@ -65,13 +73,19 @@ func addSession(ctx *cli.Context) error {
6573
return fmt.Errorf("must set a label for the session")
6674
}
6775

76+
sessTypeStr := ctx.String("type")
77+
sessType, err := parseSessionType(sessTypeStr)
78+
if err != nil {
79+
return err
80+
}
81+
6882
sessionLength := time.Second * time.Duration(ctx.Uint64("expiry"))
6983
sessionExpiry := time.Now().Add(sessionLength).Unix()
7084

7185
resp, err := client.AddSession(
7286
getAuthContext(ctx), &litrpc.AddSessionRequest{
7387
Label: label,
74-
SessionType: litrpc.SessionType_TYPE_UI_PASSWORD,
88+
SessionType: sessType,
7589
ExpiryTimestampSeconds: uint64(sessionExpiry),
7690
MailboxServerAddr: ctx.String("mailboxserveraddr"),
7791
DevServer: ctx.Bool("devserver"),
@@ -86,6 +100,17 @@ func addSession(ctx *cli.Context) error {
86100
return nil
87101
}
88102

103+
func parseSessionType(sessionType string) (litrpc.SessionType, error) {
104+
switch sessionType {
105+
case "admin":
106+
return litrpc.SessionType_TYPE_MACAROON_ADMIN, nil
107+
case "readonly":
108+
return litrpc.SessionType_TYPE_MACAROON_READONLY, nil
109+
default:
110+
return 0, fmt.Errorf("unsupported session type %s", sessionType)
111+
}
112+
}
113+
89114
var listSessionCommand = cli.Command{
90115
Name: "list",
91116
ShortName: "l",

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/improbable-eng/grpc-web v0.12.0
1111
github.com/jessevdk/go-flags v1.4.0
1212
github.com/lightninglabs/faraday v0.2.7-alpha
13-
github.com/lightninglabs/lightning-node-connect v0.1.5-alpha
13+
github.com/lightninglabs/lightning-node-connect v0.1.7-alpha
1414
github.com/lightninglabs/lndclient v0.14.0-7
1515
github.com/lightninglabs/loop v0.15.1-beta
1616
github.com/lightninglabs/pool v0.5.4-alpha.0.20220114202858-525fe156d240
@@ -25,6 +25,7 @@ require (
2525
github.com/urfave/cli v1.22.4
2626
go.etcd.io/bbolt v1.3.6
2727
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
28+
golang.org/x/net v0.0.0-20210913180222-943fd674d43e
2829
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
2930
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
3031
google.golang.org/grpc v1.39.0

go.sum

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ github.com/btcsuite/btcutil/psbt v1.0.3-0.20210527170813-e2ba6805a890 h1:0xUNvvw
105105
github.com/btcsuite/btcutil/psbt v1.0.3-0.20210527170813-e2ba6805a890/go.mod h1:LVveMu4VaNSkIRTZu2+ut0HDBRuYjqGocxDMNS1KuGQ=
106106
github.com/btcsuite/btcwallet v0.11.1-0.20200814001439-1d31f4ea6fc5/go.mod h1:YkEbJaCyN6yncq5gEp2xG0OKDwus2QxGCEXTNF27w5I=
107107
github.com/btcsuite/btcwallet v0.11.1-0.20200904022754-2c5947a45222/go.mod h1:owv9oZqM0HnUW+ByF7VqOgfs2eb0ooiePW/+Tl/i/Nk=
108+
github.com/btcsuite/btcwallet v0.11.1-0.20201207233335-415f37ff11a1/go.mod h1:P1U4LKSB/bhFQdOM7ab1XqNoBGFyFAe7eKObEBD9mIo=
108109
github.com/btcsuite/btcwallet v0.12.1-0.20210519225359-6ab9b615576f/go.mod h1:f1HuBGov5+OTp40Gh1vA+tvF6d7bbuLFTceJMRB7fXw=
109110
github.com/btcsuite/btcwallet v0.13.0/go.mod h1:iLN1lG1MW0eREm+SikmPO8AZPz5NglBTEK/ErqkjGpo=
110111
github.com/btcsuite/btcwallet v0.13.1-0.20211201210108-79de92f527dc h1:lAbAEAp4eWvsSwJfcpdHXpKz78X2sVF9aDK4nJveXmY=
@@ -323,7 +324,6 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er
323324
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
324325
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
325326
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
326-
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
327327
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
328328
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
329329
github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -603,24 +603,27 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
603603
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
604604
github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg=
605605
github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
606-
github.com/lightninglabs/aperture v0.1.6-beta h1:bhpK4O9xa0YUBFQfkfg/h/3sMAY+AOMxi9YUjg6/l/E=
607606
github.com/lightninglabs/aperture v0.1.6-beta/go.mod h1:9xl4mx778ZAzrB87nLHMqk+XQcSz8Dx/DypjWzGN1xo=
607+
github.com/lightninglabs/aperture v0.1.11-beta h1:GRnQxvDn3ZPIqC8DV1T81LCxJO33anoAAbOFxyGbUyU=
608+
github.com/lightninglabs/aperture v0.1.11-beta/go.mod h1:pl4sIilhVW6RH7FIYCugPHEPl0pmj3UE1I83Oqpj9VY=
608609
github.com/lightninglabs/faraday v0.2.7-alpha h1:lpSUk3RFfgr4/OCx1OdJ2AMHCAiTObK+5o54ml8ceHs=
609610
github.com/lightninglabs/faraday v0.2.7-alpha/go.mod h1:77P9EctYhneIXLvm9a6ylV9LCht/rj7j8mLwXpBgxB8=
610611
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc=
611612
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
612-
github.com/lightninglabs/lightning-node-connect v0.1.5-alpha h1:6Jguz6wXSaV2KVs+mvEDATQdNMvKiTmuQeRGMzvarTw=
613-
github.com/lightninglabs/lightning-node-connect v0.1.5-alpha/go.mod h1:xsDBDnSzHalal3K4gbnVSrbWVbV25sHrm96p3+lASt0=
613+
github.com/lightninglabs/lightning-node-connect v0.1.7-alpha h1:M2g8Il/DWhRvwZIEBER1QVDeIj9OTM0+DE7fXrLqc10=
614+
github.com/lightninglabs/lightning-node-connect v0.1.7-alpha/go.mod h1:jxSnezQYIvhNXqjyyiMEmdpOURrdVaujPZV6zGCVi8o=
614615
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2 h1:Er1miPZD2XZwcfE4xoS5AILqP1mj7kqnhbBSxW9BDxY=
615616
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2/go.mod h1:antQGRDRJiuyQF6l+k6NECCSImgCpwaZapATth2Chv4=
616617
github.com/lightninglabs/lndclient v0.11.0-4/go.mod h1:8/cTKNwgL87NX123gmlv3Xh6p1a7pvzu+40Un3PhHiI=
618+
github.com/lightninglabs/lndclient v0.12.0-9/go.mod h1:L0R2VOaLxMylGbxgnfiZGc0hMDIIgj91cfgwGuFz9kU=
617619
github.com/lightninglabs/lndclient v0.14.0-5/go.mod h1:2kH9vNoc29ghIkfMjxwSeK8yCxsYfR80XAJ9PU/QWWk=
618620
github.com/lightninglabs/lndclient v0.14.0-7 h1:muqPju9ixBtQNcO0SkvbZ2b2oORUMRqQ4e+aC077Qa8=
619621
github.com/lightninglabs/lndclient v0.14.0-7/go.mod h1:2kH9vNoc29ghIkfMjxwSeK8yCxsYfR80XAJ9PU/QWWk=
620622
github.com/lightninglabs/loop v0.15.1-beta h1:X4qth5qAdpgKarmcltO85HxMze3Wrk8FzI46Cwt9H4A=
621623
github.com/lightninglabs/loop v0.15.1-beta/go.mod h1:9TawqLzvjDP4pswZ8QkvTcBqH+wGKBffP+r6mFGBVi4=
622624
github.com/lightninglabs/neutrino v0.11.0/go.mod h1:CuhF0iuzg9Sp2HO6ZgXgayviFTn1QHdSTJlMncK80wg=
623625
github.com/lightninglabs/neutrino v0.11.1-0.20200316235139-bffc52e8f200/go.mod h1:MlZmoKa7CJP3eR1s5yB7Rm5aSyadpKkxqAwLQmog7N0=
626+
github.com/lightninglabs/neutrino v0.11.1-0.20201210023533-e1978372d15e/go.mod h1:KDWfQDKp+CFBxO1t2NRmWuagTY2sYIjpHB1k5vrojTI=
624627
github.com/lightninglabs/neutrino v0.12.1/go.mod h1:GlKninWpRBbL7b8G0oQ36/8downfnFwKsr0hbRA6E/E=
625628
github.com/lightninglabs/neutrino v0.13.0 h1:j3PKWEJCwqwMn/qLASz2j0IuCF6AumS9DaM0i0pM/nY=
626629
github.com/lightninglabs/neutrino v0.13.0/go.mod h1:GlKninWpRBbL7b8G0oQ36/8downfnFwKsr0hbRA6E/E=
@@ -636,13 +639,13 @@ github.com/lightningnetwork/lightning-onion v1.0.2-0.20210520211913-522b799e65b1
636639
github.com/lightningnetwork/lightning-onion v1.0.2-0.20210520211913-522b799e65b1/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4=
637640
github.com/lightningnetwork/lnd v0.11.0-beta/go.mod h1:CzArvT7NFDLhVyW06+NJWSuWFmE6Ea+AjjA3txUBqTM=
638641
github.com/lightningnetwork/lnd v0.11.1-beta/go.mod h1:PGIgxy8aH70Li33YVYkHSaCM8m8LjEevk5h1Dpldrr4=
642+
github.com/lightningnetwork/lnd v0.12.0-beta/go.mod h1:2GyP1IG1kXV5Af/LOCxnXfux1OP3fAGr8zptS5PB2YI=
639643
github.com/lightningnetwork/lnd v0.13.0-beta.rc5.0.20210728112744-ebabda671786/go.mod h1:3cmukt9wR4PX1va9Q78gmqSPYd6yhV1wcFemM5F+kT8=
640644
github.com/lightningnetwork/lnd v0.14.0-beta/go.mod h1:qqOImM4QBKeIXsmUUsJznAbAaEF9iAPHAwfBZf9ld4Y=
641645
github.com/lightningnetwork/lnd v0.14.1-beta/go.mod h1:o7zDwjZXm/bPP48qjwsqnZvvITyQl+fUv6UVoV4o+J8=
642646
github.com/lightningnetwork/lnd v0.14.2-beta h1:v5Xgf0HjgA+umoinNrihMSoAuy52tYQnxCzX0wFaRwQ=
643647
github.com/lightningnetwork/lnd v0.14.2-beta/go.mod h1:BKTR+jbfcyFwsOPb3m8HaM09YmZF/SsbWd5UTCgDZlo=
644648
github.com/lightningnetwork/lnd/cert v1.0.2/go.mod h1:fmtemlSMf5t4hsQmcprSoOykypAPp+9c+0d0iqTScMo=
645-
github.com/lightningnetwork/lnd/cert v1.0.2/go.mod h1:fmtemlSMf5t4hsQmcprSoOykypAPp+9c+0d0iqTScMo=
646649
github.com/lightningnetwork/lnd/cert v1.0.3/go.mod h1:3MWXVLLPI0Mg0XETm9fT4N9Vyy/8qQLmaM5589bEggM=
647650
github.com/lightningnetwork/lnd/cert v1.1.0 h1:Vgmse23SOB/ODIj+I5Utq1yuKLPbWQ34gUoNKfDs4pk=
648651
github.com/lightningnetwork/lnd/cert v1.1.0/go.mod h1:3MWXVLLPI0Mg0XETm9fT4N9Vyy/8qQLmaM5589bEggM=
@@ -960,19 +963,16 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
960963
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
961964
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
962965
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
963-
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
964966
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
965967
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
966968
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
967969
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
968970
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
969971
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
970972
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
971-
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
972973
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
973974
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
974975
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
975-
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
976976
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
977977
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
978978
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
@@ -989,7 +989,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
989989
golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
990990
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
991991
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
992-
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
993992
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
994993
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
995994
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
@@ -1051,7 +1050,6 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
10511050
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
10521051
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
10531052
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
1054-
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
10551053
golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
10561054
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
10571055
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -1315,7 +1313,6 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG
13151313
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
13161314
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
13171315
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
1318-
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
13191316
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
13201317
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
13211318
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=

session/interface.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package session
22

33
import (
4-
"encoding/binary"
54
"fmt"
65
"time"
76

87
"github.com/btcsuite/btcd/btcec"
98
"github.com/lightninglabs/lightning-node-connect/mailbox"
9+
"gopkg.in/macaroon-bakery.v2/bakery"
1010
"gopkg.in/macaroon.v2"
1111
)
1212

@@ -30,6 +30,13 @@ const (
3030
StateExpired State = 3
3131
)
3232

33+
// MacaroonRecipe defines the permissions and caveats that should be used
34+
// to bake a macaroon.
35+
type MacaroonRecipe struct {
36+
Permissions []bakery.Op
37+
Caveats []macaroon.Caveat
38+
}
39+
3340
// Session is a struct representing a long-term Terminal Connect session.
3441
type Session struct {
3542
Label string
@@ -39,7 +46,7 @@ type Session struct {
3946
ServerAddr string
4047
DevServer bool
4148
MacaroonRootKey uint64
42-
Macaroon *macaroon.Macaroon
49+
MacaroonRecipe *MacaroonRecipe
4350
PairingSecret [mailbox.NumPasswordBytes]byte
4451
LocalPrivateKey *btcec.PrivateKey
4552
LocalPublicKey *btcec.PublicKey
@@ -48,7 +55,8 @@ type Session struct {
4855

4956
// NewSession creates a new session with the given user-defined parameters.
5057
func NewSession(label string, typ Type, expiry time.Time, serverAddr string,
51-
devServer bool) (*Session, error) {
58+
devServer bool, perms []bakery.Op, caveats []macaroon.Caveat) (*Session,
59+
error) {
5260

5361
_, pairingSecret, err := mailbox.NewPassword()
5462
if err != nil {
@@ -60,9 +68,12 @@ func NewSession(label string, typ Type, expiry time.Time, serverAddr string,
6068
return nil, fmt.Errorf("error deriving private key: %v", err)
6169
}
6270
pubKey := privateKey.PubKey()
63-
macRootKey := binary.BigEndian.Uint64(pubKey.SerializeCompressed()[0:8])
6471

65-
return &Session{
72+
var macRootKeyBase [4]byte
73+
copy(macRootKeyBase[:], pubKey.SerializeCompressed())
74+
macRootKey := NewSuperMacaroonRootKeyID(macRootKeyBase)
75+
76+
sess := &Session{
6677
Label: label,
6778
State: StateCreated,
6879
Type: typ,
@@ -74,7 +85,16 @@ func NewSession(label string, typ Type, expiry time.Time, serverAddr string,
7485
LocalPrivateKey: privateKey,
7586
LocalPublicKey: pubKey,
7687
RemotePublicKey: nil,
77-
}, nil
88+
}
89+
90+
if perms != nil || caveats != nil {
91+
sess.MacaroonRecipe = &MacaroonRecipe{
92+
Permissions: perms,
93+
Caveats: caveats,
94+
}
95+
}
96+
97+
return sess, nil
7898
}
7999

80100
// Store is the interface a persistent storage must implement for storing and

session/macaroon.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package session
2+
3+
import (
4+
"bytes"
5+
"encoding/binary"
6+
"encoding/hex"
7+
"strconv"
8+
9+
"github.com/lightningnetwork/lnd/lnrpc"
10+
"google.golang.org/protobuf/proto"
11+
"gopkg.in/macaroon-bakery.v2/bakery"
12+
"gopkg.in/macaroon.v2"
13+
)
14+
15+
var (
16+
// SuperMacaroonRootKeyPrefix is the prefix we set on a super macaroon's
17+
// root key to clearly mark it as such.
18+
SuperMacaroonRootKeyPrefix = [4]byte{0xFF, 0xEE, 0xDD, 0xCC}
19+
)
20+
21+
// NewSuperMacaroonRootKeyID returns a new macaroon root key ID that has the
22+
// prefix to mark it as a super macaroon root key.
23+
func NewSuperMacaroonRootKeyID(id [4]byte) uint64 {
24+
rootKeyBytes := make([]byte, 8)
25+
copy(rootKeyBytes[:], SuperMacaroonRootKeyPrefix[:])
26+
copy(rootKeyBytes[4:], id[:])
27+
return binary.BigEndian.Uint64(rootKeyBytes)
28+
}
29+
30+
// ParseMacaroon parses a hex encoded macaroon into its native struct.
31+
func ParseMacaroon(macHex string) (*macaroon.Macaroon, error) {
32+
macBytes, err := hex.DecodeString(macHex)
33+
if err != nil {
34+
return nil, err
35+
}
36+
37+
mac := &macaroon.Macaroon{}
38+
if err := mac.UnmarshalBinary(macBytes); err != nil {
39+
return nil, err
40+
}
41+
42+
return mac, nil
43+
}
44+
45+
// IsSuperMacaroon returns true if the given hex encoded macaroon is a super
46+
// macaroon baked by LiT which can be identified by its root key ID.
47+
func IsSuperMacaroon(macHex string) bool {
48+
mac, err := ParseMacaroon(macHex)
49+
if err != nil {
50+
return false
51+
}
52+
53+
rawID := mac.Id()
54+
if rawID[0] != byte(bakery.LatestVersion) {
55+
return false
56+
}
57+
decodedID := &lnrpc.MacaroonId{}
58+
idProto := rawID[1:]
59+
err = proto.Unmarshal(idProto, decodedID)
60+
if err != nil {
61+
return false
62+
}
63+
64+
// The storage ID is a string representation of a 64bit unsigned number.
65+
rootKeyID, err := strconv.ParseUint(string(decodedID.StorageId), 10, 64)
66+
if err != nil {
67+
return false
68+
}
69+
70+
return isSuperMacaroonRootKeyID(rootKeyID)
71+
}
72+
73+
// isSuperMacaroonRootKeyID returns true if the given macaroon root key ID (also
74+
// known as storage ID) is a super macaroon, which can be identified by its
75+
// first 4 bytes.
76+
func isSuperMacaroonRootKeyID(rootKeyID uint64) bool {
77+
rootKeyBytes := make([]byte, 8)
78+
binary.BigEndian.PutUint64(rootKeyBytes, rootKeyID)
79+
return bytes.HasPrefix(rootKeyBytes, SuperMacaroonRootKeyPrefix[:])
80+
}

session/macaroon_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package session
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
var (
10+
// testMacHex is a read-only supermacaroon.
11+
testMacHex = "0201036c6e6402f802030a1011540404373b4d0b3682b15ea7af60c" +
12+
"c121431383434313932313339323432393138343738341a0f0a076163636" +
13+
"f756e741204726561641a0f0a0761756374696f6e1204726561641a0d0a0" +
14+
"561756469741204726561641a0c0a04617574681204726561641a0c0a046" +
15+
"96e666f1204726561641a100a08696e7369676874731204726561641a100" +
16+
"a08696e766f696365731204726561641a0f0a046c6f6f701202696e12036" +
17+
"f75741a100a086d616361726f6f6e1204726561641a0f0a076d657373616" +
18+
"7651204726561641a100a086f6666636861696e1204726561641a0f0a076" +
19+
"f6e636861696e1204726561641a0d0a056f726465721204726561641a0d0" +
20+
"a0570656572731204726561641a0d0a0572617465731204726561641a160" +
21+
"a0e7265636f6d6d656e646174696f6e1204726561641a0e0a067265706f7" +
22+
"2741204726561641a130a0b73756767657374696f6e731204726561641a0" +
23+
"c0a04737761701204726561641a0d0a057465726d7312047265616400000" +
24+
"6202362c91888e95dfbbf1eb995bd0fef2b549e2de7f4e9fa11aff445273" +
25+
"60a6caf"
26+
)
27+
28+
func TestSuperMacaroonRootKeyID(t *testing.T) {
29+
someBytes := [4]byte{02, 03, 44, 88}
30+
rootKeyID := NewSuperMacaroonRootKeyID(someBytes)
31+
require.True(t, isSuperMacaroonRootKeyID(rootKeyID))
32+
require.False(t, isSuperMacaroonRootKeyID(123))
33+
}
34+
35+
func TestIsSuperMacaroon(t *testing.T) {
36+
require.True(t, IsSuperMacaroon(testMacHex))
37+
}

0 commit comments

Comments
 (0)