Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cookie authentication for eclair json-rpc api #2040

Closed
wants to merge 9 commits into from

Conversation

Thoragh
Copy link
Contributor

@Thoragh Thoragh commented Oct 28, 2021

fixes #1437

This PR add cookie authentication for eclair API. It is enabled by default when the API is enabled and the default cookie file is .cookie in the datadir.
It is possible to have both cookie and password authentication enabled at the same time and the API can be enabled without password. I used a separate configuration option for flag because I don't like how it is done in bitcoind where cookie depends on if an rpcpassword is set.

It is also possible to to use eclair.api.cookie-group-readable to make the generated cookie file group readable on Linux.

@codecov-commenter
Copy link

codecov-commenter commented Oct 28, 2021

Codecov Report

Merging #2040 (e4ac102) into master (4f458d3) will decrease coverage by 0.00%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master    #2040      +/-   ##
==========================================
- Coverage   87.54%   87.54%   -0.01%     
==========================================
  Files         161      162       +1     
  Lines       12599    12607       +8     
  Branches      526      524       -2     
==========================================
+ Hits        11030    11037       +7     
- Misses       1569     1570       +1     
Impacted Files Coverage Δ
...ir-core/src/main/scala/fr/acinq/eclair/Setup.scala 79.77% <ø> (ø)
...cala/fr/acinq/eclair/payment/relay/NodeRelay.scala 95.93% <0.00%> (-1.63%) ⬇️
...main/scala/fr/acinq/eclair/router/Validation.scala 90.76% <0.00%> (-1.54%) ⬇️
...clair/channel/publish/ReplaceableTxPublisher.scala 86.20% <0.00%> (-1.15%) ⬇️
...src/main/scala/fr/acinq/eclair/crypto/Sphinx.scala 100.00% <0.00%> (ø)
...in/scala/fr/acinq/eclair/channel/ChannelData.scala 100.00% <0.00%> (ø)
...n/scala/fr/acinq/eclair/json/JsonSerializers.scala 87.09% <0.00%> (ø)
...in/scala/fr/acinq/eclair/wire/protocol/Onion.scala
...a/fr/acinq/eclair/wire/protocol/OnionRouting.scala 60.00% <0.00%> (ø)
...a/fr/acinq/eclair/wire/protocol/PaymentOnion.scala 98.73% <0.00%> (ø)
... and 3 more

@Thoragh
Copy link
Contributor Author

Thoragh commented Nov 1, 2021

I have tested that this pr work on Windows and Linux. It would be grate if someone could try on Mac OS since I can't.

@Thoragh Thoragh marked this pull request as ready for review November 2, 2021 13:21
Copy link
Member

@t-bast t-bast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this!
I haven't tested it yet as I believe we should change some of the requirements first.

eclair.api.port | API HTTP port | 8080
eclair.api.password | API password (BASIC) | "" (must be set if the API is enabled)
eclair.api.password | API password (BASIC) | "" (change to something else if you want to enable password authentication)
eclair.api.cookie-enabled | API cookie authentication | true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be consistent with bitcoin core's naming:

Suggested change
eclair.api.cookie-enabled | API cookie authentication | true
eclair.api.safecookie | Enable API safe cookie authentication | true

@@ -13,7 +13,10 @@ eclair {
enabled = false // disabled by default for security reasons
binding-ip = "127.0.0.1"
port = 8080
password = "" // password for basic auth, must be non empty if json-rpc api is enabled
password = "" // password for basic auth, must be non empty to enable password authentication
cookie-enabled = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cookie-enabled = true
use-safecookie = true // NB: when using cookie authentication, password authentication will be automatically disabled

password = "" // password for basic auth, must be non empty if json-rpc api is enabled
password = "" // password for basic auth, must be non empty to enable password authentication
cookie-enabled = true
cookie-group-readable = false
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment explaining that field.

None
}
if (apiPassword.isEmpty && apiCookiePassword.isEmpty) {
throw new RuntimeException("json-rpc api requires that either password or cookie is enabled")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of an unnamed exception, you should replace the EmptyAPIPasswordException in Setup.scala with a APICredentialsNotConfiguredException

Comment on lines +88 to +89
override val password: Option[String] = apiPassword
override val cookiePassword: Option[String] = apiCookiePassword
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really shouldn't support both cookie and password auth at the same time.
The reason you would enable cookie authentication is to explicitly get rid of the user/password auth.
When cookie auth is enabled, this should automatically disable password auth.

I think we should force the user to clear its password field in reference.conf, like Bitcoin Core does, as this makes it very explicit for the user, and we should verify that they have done so.

Once that's done, I don't think we need to modify the Service class, there will still be a single password field that will be non-optional (containing either the user password or cookie password depending on which is enabled).

if (groupReadable) {
posixView.setPermissions(PosixFilePermissions.fromString("rw-r-----"))
} else {
posixView.setPermissions(PosixFilePermissions.fromString("rw-------"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to change it in that case? What are the default permissions if you don't do anything?

Comment on lines +121 to +128
val aclEntry = AclEntry.newBuilder()
.setPermissions(Set.from(AclEntryPermission.values()).asJava)
.setPrincipal(aclView.getOwner)
.setType(AclEntryType.ALLOW)
.build()
// setAcl() replaces all acl entries for the file.
// That means setting acl with an list containing only an entry that gives access to the owner, everyone else lose access to the file.
aclView.setAcl(List(aclEntry).asJava)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that necessary if you can't make the file group-readable on windows?
What exactly are you changing here compared to the default permissions?

// That means setting acl with an list containing only an entry that gives access to the owner, everyone else lose access to the file.
aclView.setAcl(List(aclEntry).asJava)
if (groupReadable) {
logger.warn("could not make the .cookie file group readable")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be a warning, it should be an exception.
We should note in the reference.conf that this field cannot be set to true on windows.

logger.warn("could not change the permissions of the .cookie file")
}

Files.writeString(path, s"${Service.CookieUserName}:$hexPassword", StandardCharsets.UTF_8)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like we should use ASCII instead of UTF8 here, we don't actually need UTF8, do we?

@t-bast
Copy link
Member

t-bast commented May 9, 2022

Closing this inactive PR.

@t-bast t-bast closed this May 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: implement cookie authentication for eclair RPC
3 participants