Merge pull request #7592 from sangaman/gen-default-macaroons-independently

lnd: generate default macaroons independently
This commit is contained in:
Oliver Gugger 2023-04-27 14:04:27 +02:00 committed by GitHub
commit 7854b73892
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 37 deletions

View file

@ -470,14 +470,10 @@ func (d *DefaultWalletImpl) BuildWalletConfig(ctx context.Context,
// If the user requested a stateless initialization, no macaroon
// files should be created.
if !walletInitParams.StatelessInit &&
!lnrpc.FileExists(d.cfg.AdminMacPath) &&
!lnrpc.FileExists(d.cfg.ReadMacPath) &&
!lnrpc.FileExists(d.cfg.InvoiceMacPath) {
// Create macaroon files for lncli to use if they don't
// exist.
err = genMacaroons(
if !walletInitParams.StatelessInit {
// Create default macaroon files for lncli to use if
// they don't exist.
err = genDefaultMacaroons(
ctx, macaroonService, d.cfg.AdminMacPath,
d.cfg.ReadMacPath, d.cfg.InvoiceMacPath,
)

View file

@ -13,8 +13,14 @@
the entire retribution struct. This reduces the amount of data that needs to
be held in memory.
## Misc
* [Generate default macaroons
independently](https://github.com/lightningnetwork/lnd/pull/7592) on wallet
unlock or create.
# Contributors (Alphabetical Order)
* Daniel McNally
* Elle Mouton
* Jordi Montes

56
lnd.go
View file

@ -690,46 +690,64 @@ func bakeMacaroon(ctx context.Context, svc *macaroons.Service,
return mac.M().MarshalBinary()
}
// genMacaroons generates three macaroon files; one admin-level, one for
// invoice access and one read-only. These can also be used to generate more
// granular macaroons.
func genMacaroons(ctx context.Context, svc *macaroons.Service,
// saveMacaroon bakes a macaroon with the specified macaroon permissions and
// writes it to a file with the given filename and file permissions.
func saveMacaroon(ctx context.Context, svc *macaroons.Service, filename string,
macaroonPermissions []bakery.Op, filePermissions os.FileMode) error {
macaroonBytes, err := bakeMacaroon(ctx, svc, macaroonPermissions)
if err != nil {
return err
}
err = os.WriteFile(filename, macaroonBytes, filePermissions)
if err != nil {
_ = os.Remove(filename)
return err
}
return nil
}
// genDefaultMacaroons checks for three default macaroon files and generates
// them if they do not exist; one admin-level, one for invoice access and one
// read-only. Each macaroon is checked and created independently to ensure all
// three exist. The admin macaroon can also be used to generate more granular
// macaroons.
func genDefaultMacaroons(ctx context.Context, svc *macaroons.Service,
admFile, roFile, invoiceFile string) error {
// First, we'll generate a macaroon that only allows the caller to
// access invoice related calls. This is useful for merchants and other
// services to allow an isolated instance that can only query and
// modify invoices.
invoiceMacBytes, err := bakeMacaroon(ctx, svc, invoicePermissions)
if !lnrpc.FileExists(invoiceFile) {
err := saveMacaroon(
ctx, svc, invoiceFile, invoicePermissions, 0644,
)
if err != nil {
return err
}
err = ioutil.WriteFile(invoiceFile, invoiceMacBytes, 0644)
if err != nil {
_ = os.Remove(invoiceFile)
return err
}
// Generate the read-only macaroon and write it to a file.
roBytes, err := bakeMacaroon(ctx, svc, readPermissions)
if !lnrpc.FileExists(roFile) {
err := saveMacaroon(
ctx, svc, roFile, readPermissions, 0644,
)
if err != nil {
return err
}
if err = ioutil.WriteFile(roFile, roBytes, 0644); err != nil {
_ = os.Remove(roFile)
return err
}
// Generate the admin macaroon and write it to a file.
admBytes, err := bakeMacaroon(ctx, svc, adminPermissions())
if !lnrpc.FileExists(admFile) {
err := saveMacaroon(
ctx, svc, admFile, adminPermissions(),
adminMacaroonFilePermissions,
)
if err != nil {
return err
}
err = ioutil.WriteFile(admFile, admBytes, adminMacaroonFilePermissions)
if err != nil {
_ = os.Remove(admFile)
return err
}
return nil