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 // If the user requested a stateless initialization, no macaroon
// files should be created. // files should be created.
if !walletInitParams.StatelessInit && if !walletInitParams.StatelessInit {
!lnrpc.FileExists(d.cfg.AdminMacPath) && // Create default macaroon files for lncli to use if
!lnrpc.FileExists(d.cfg.ReadMacPath) && // they don't exist.
!lnrpc.FileExists(d.cfg.InvoiceMacPath) { err = genDefaultMacaroons(
// Create macaroon files for lncli to use if they don't
// exist.
err = genMacaroons(
ctx, macaroonService, d.cfg.AdminMacPath, ctx, macaroonService, d.cfg.AdminMacPath,
d.cfg.ReadMacPath, d.cfg.InvoiceMacPath, 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 the entire retribution struct. This reduces the amount of data that needs to
be held in memory. be held in memory.
## Misc
* [Generate default macaroons
independently](https://github.com/lightningnetwork/lnd/pull/7592) on wallet
unlock or create.
# Contributors (Alphabetical Order) # Contributors (Alphabetical Order)
* Daniel McNally
* Elle Mouton * Elle Mouton
* Jordi Montes * Jordi Montes

74
lnd.go
View file

@ -690,46 +690,64 @@ func bakeMacaroon(ctx context.Context, svc *macaroons.Service,
return mac.M().MarshalBinary() return mac.M().MarshalBinary()
} }
// genMacaroons generates three macaroon files; one admin-level, one for // saveMacaroon bakes a macaroon with the specified macaroon permissions and
// invoice access and one read-only. These can also be used to generate more // writes it to a file with the given filename and file permissions.
// granular macaroons. func saveMacaroon(ctx context.Context, svc *macaroons.Service, filename string,
func genMacaroons(ctx context.Context, svc *macaroons.Service, 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 { admFile, roFile, invoiceFile string) error {
// First, we'll generate a macaroon that only allows the caller to // First, we'll generate a macaroon that only allows the caller to
// access invoice related calls. This is useful for merchants and other // access invoice related calls. This is useful for merchants and other
// services to allow an isolated instance that can only query and // services to allow an isolated instance that can only query and
// modify invoices. // modify invoices.
invoiceMacBytes, err := bakeMacaroon(ctx, svc, invoicePermissions) if !lnrpc.FileExists(invoiceFile) {
if err != nil { err := saveMacaroon(
return err ctx, svc, invoiceFile, invoicePermissions, 0644,
} )
err = ioutil.WriteFile(invoiceFile, invoiceMacBytes, 0644) if err != nil {
if err != nil { return err
_ = os.Remove(invoiceFile) }
return err
} }
// Generate the read-only macaroon and write it to a file. // Generate the read-only macaroon and write it to a file.
roBytes, err := bakeMacaroon(ctx, svc, readPermissions) if !lnrpc.FileExists(roFile) {
if err != nil { err := saveMacaroon(
return err ctx, svc, roFile, readPermissions, 0644,
} )
if err = ioutil.WriteFile(roFile, roBytes, 0644); err != nil { if err != nil {
_ = os.Remove(roFile) return err
return err }
} }
// Generate the admin macaroon and write it to a file. // Generate the admin macaroon and write it to a file.
admBytes, err := bakeMacaroon(ctx, svc, adminPermissions()) if !lnrpc.FileExists(admFile) {
if err != nil { err := saveMacaroon(
return err ctx, svc, admFile, adminPermissions(),
} adminMacaroonFilePermissions,
)
err = ioutil.WriteFile(admFile, admBytes, adminMacaroonFilePermissions) if err != nil {
if err != nil { return err
_ = os.Remove(admFile) }
return err
} }
return nil return nil