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

init: Add option for rpccookie permissions (replace 26088) #28167

Merged
merged 4 commits into from
Jun 27, 2024

Conversation

willcl-ark
Copy link
Member

@willcl-ark willcl-ark commented Jul 27, 2023

This PR picks up #26088 by aureleoules which adds a bitcoind launch option -rpccookieperms to set the file permissions of the cookie generated by bitcoin core.

Example usage to make the generated cookie group-readable: ./src/bitcoind -rpccookieperms=group.

Accepted values for -rpccookieperms are [owner|group|all]. We let fs::perms handle platform-specific permissions changes.

@DrahtBot
Copy link
Contributor

DrahtBot commented Jul 27, 2023

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage

For detailed information about the code coverage, see the test coverage report.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK achow101, ryanofsky, tdb3
Approach ACK jamesob

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #29641 (scripted-diff: Use LogInfo/LogDebug over LogPrintf/LogPrint by maflcko)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

src/httprpc.cpp Outdated Show resolved Hide resolved
src/httprpc.cpp Outdated Show resolved Hide resolved
src/httprpc.cpp Outdated Show resolved Hide resolved
@DrahtBot
Copy link
Contributor

Are you still working on this?

@willcl-ark
Copy link
Member Author

Updated to address luke's comment and added a test to ensure rpccookieperms are being applied

@willcl-ark willcl-ark force-pushed the 2023-07-rpccookie-perms branch 4 times, most recently from ee4ead3 to 65d43b1 Compare November 21, 2023 09:46
@willcl-ark
Copy link
Member Author

Rebased now that #28905 is merged.

Comment on lines 88 to 90
if ((p & fs::perms::set_uid) != fs::perms::none) special = '4';
if ((p & fs::perms::set_gid) != fs::perms::none) special = '2';
if ((p & fs::perms::sticky_bit) != fs::perms::none) special = '1';
Copy link
Member

Choose a reason for hiding this comment

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

This won't work if multiple bits are set

Copy link
Member

Choose a reason for hiding this comment

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

These bits seem to typically manifest by replacing the 'x' field with either 's' (setuid/setgid+executable), 'S' (setuid/setgid WITHOUT executable), 't' (sticky+exec), or 'T' (sticky NO exec)

@kristapsk
Copy link
Contributor

Should the permissions that can be set limited here? There is no reason to ever set +x on an RPC cookie file.

@luke-jr
Copy link
Member

luke-jr commented Dec 30, 2023

I'm not sure there's a reason to ever set +w either... maybe it should just be -rpccookieaccess user/group/all or something

@kristapsk
Copy link
Contributor

I'm not sure there's a reason to ever set +w either... maybe it should just be -rpccookieaccess user/group/all or something

Agree, makes sense. Giving read access to other users is the only use case of this functionality I know of.

luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 13, 2024
Set owner read/write permissions on cookie files by default.
On Windows this will cause the write bit to be set.

Github-Pull: bitcoin#28167
Rebased-From: 35df853
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 13, 2024
Helpers to convert from pemissions to strings and visa-versa.

Github-Pull: bitcoin#28167
Rebased-From: e7c7bdc
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 13, 2024
Add a bitcoind launch option `-rpccookieperms` to configure the file
permissions of the cookie on Unix systems.

Github-Pull: bitcoin#28167
Rebased-From: ae7ec04
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 13, 2024
Tests various perms on non-Windows OSes

Github-Pull: bitcoin#28167
Rebased-From: ab3245f
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 13, 2024
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 13, 2024
Co-authored-by: Will Clark <will@256k1.dev>

Github-Pull: bitcoin#28167
Rebased-From: 7456c3a
Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Code review ACK e479803. Seems very clean now with the test simplification and without the win32 stuff.

return false;
}
std::error_code code;
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "init: add option for rpccookie permissions" (7ad5349)

Could move this variable inside the if statement since it's not used afterwards.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved in 9eff560

@DrahtBot DrahtBot requested a review from tdb3 June 24, 2024 23:07
Copy link
Contributor

@tdb3 tdb3 left a comment

Choose a reason for hiding this comment

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

re ACK e479803

Ran rpc_users locally (passed).
Re-ran the manual check in #28167 (review) (same results).
Left one minor nit.


UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id);
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id);
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
UniValue JSONRPCError(int code, const std::string& message);

/** Generate a new RPC authentication cookie and write it to disk */
bool GenerateAuthCookie(std::string *cookie_out);
bool GenerateAuthCookie(std::string* cookie_out, std::optional<fs::perms> cookie_perms);
Copy link
Contributor

@tdb3 tdb3 Jun 25, 2024

Choose a reason for hiding this comment

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

nit: If touching this file again, may want to consider defining a default argument for cookie_perms. Since std::optional is used, I'm assuming the intent is not to force the caller to provide an optional object.

diff --git a/src/rpc/request.h b/src/rpc/request.h
index b40df16631..c7e723d962 100644
--- a/src/rpc/request.h
+++ b/src/rpc/request.h
@@ -19,7 +19,7 @@ std::string JSONRPCReply(const UniValue& result, const UniValue& error, const Un
 UniValue JSONRPCError(int code, const std::string& message);
 
 /** Generate a new RPC authentication cookie and write it to disk */
-bool GenerateAuthCookie(std::string* cookie_out, std::optional<fs::perms> cookie_perms);
+bool GenerateAuthCookie(std::string* cookie_out, std::optional<fs::perms> cookie_perms=std::nullopt);
 /** Read the RPC authentication cookie from disk */
 bool GetAuthCookie(std::string *cookie_out);
 /** Delete RPC authentication cookie from disk */

GenerateAuthCookie() is currently used with the argument provided, so not a big deal either way.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added in 49d5bfd

def test_rpccookieperms(self):
p = {"owner": 0o600, "group": 0o640, "all": 0o644}

if os.name == 'nt':
Copy link
Member

Choose a reason for hiding this comment

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

In 31cc8bc "test: add rpccookieperms test"

Since #29034, the preferred convention is to use platform.system() rather than os.name.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, updated in 49d5bfd

p = {"owner": 0o600, "group": 0o640, "all": 0o644}

if os.name == 'nt':
raise SkipTest(f"Skip cookie file permissions checks as OS detected as: {os.name=}")
Copy link
Member

Choose a reason for hiding this comment

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

In 31cc8bc "test: add rpccookieperms test"

This is incorrect. It causes the entire test file to be marked as skipped (different exit code, marked differently in the test runner output) even though everything else ran. The correct thing here is to skip this individual case, which can be achieved by simply returning.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch. Might also be good to print a log message before returning for awareness.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh no! fixed in 49d5bfd

Comment on lines 66 to 67
std::string PermsToString(fs::perms p);
std::optional<fs::perms> StringToPerms(const std::string& s);
Copy link
Member

Choose a reason for hiding this comment

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

In 38af55e "util: add PermsToString and StringToPerms"

nit: This naming is a little bit confusing to me since it suggests that these functions are inverses of each other, but they're not as their string outputs are not compatible.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree on reflection, gave them new names in 49d5bfd

Comment on lines 92 to 93
/** the umask determines what permissions are used to create this file -
* these are set to 0077 in common/system.cpp.
Copy link
Member

Choose a reason for hiding this comment

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

In 7ad5349 "init: add option for rpccookie permissions"

This comment is removed, but the umask is still what sets the permissions in the default case.

Since we can set the permissions explicitly in this function, I think it would make sense to always set them with owner as default rather than relying on the umask that happens somewhere else.

Copy link
Contributor

Choose a reason for hiding this comment

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

re: #28167 (comment)

This comment is removed, but the umask is still what sets the permissions in the default case.

Good catch, it would be good to add back the comment.

Since we can set the permissions explicitly in this function, I think it would make sense to always set them with owner as default rather than relying on the umask that happens somewhere else.

The PR was actually doing this originally, but I suggested doing the opposite in #28167 (comment). It makes sense to me that when -rpccookieperms option is not specified, bitcoind would not set permissions on this file, just like it is not setting permissions on other files.

It seems fragile to rely on the fs::permissions call doing the right thing on all filesystems, when its behavior is not specified anywhere and we have never relied on it before. The documentation points to some odd ways it can be behave like "changing some bits may automatically change others" and we don't know what unusual things it may do on fuse filesystems or filesystems that use ACLs.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've un-removed the comment in 9eff560, as I agree with @ryanofsky that not changing the existant behaviour is the "safer" default, and new behaviour can be introduced with the new option.

Copy link
Contributor

@tdb3 tdb3 left a comment

Choose a reason for hiding this comment

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

re ACK 4f6b00c

Ran rpc_users locally (passed).
Re-ran the manual check in #28167 (review) (same results).
Also sanity checked on a Windows machine running Python 3.9.13 that platform.system() does return "Windows".
Left one minor nit.

src/util/fs_helpers.h Outdated Show resolved Hide resolved
@DrahtBot DrahtBot requested a review from ryanofsky June 27, 2024 13:33
PermsToSymbolicString will convert from fs::perms to string type
'rwxrwxrwx'.

InterpretPermString will convert from a user-supplied "perm string" such
as 'owner', 'group' or 'all, into appropriate fs::perms.
willcl-ark and others added 3 commits June 27, 2024 15:08
Add a bitcoind launch option `-rpccookieperms` to configure the file
permissions of the cookie on Unix systems.
Tests various perms on non-Windows OSes
Co-authored-by: tdb3 <106488469+tdb3@users.noreply.github.com>
@DrahtBot
Copy link
Contributor

🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the
documentation.

Possibly this is due to a silent merge conflict (the changes in this pull request being
incompatible with the current code in the target branch). If so, make sure to rebase on the latest
commit of the target branch.

Leave a comment here, if you need help tracking down a confusing failure.

Debug: https://github.com/bitcoin/bitcoin/runs/26763232631

@achow101
Copy link
Member

ACK 73f0a6c

@DrahtBot DrahtBot requested a review from tdb3 June 27, 2024 18:20
Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

Code review ACK 73f0a6c. Main change since last review is no longer throwing a skip exception in the rpc test on windows, so other checks can run after it, and overall test result is passing, not skipped. Also were clarifying renames and documentation improvements.

Copy link
Contributor

@tdb3 tdb3 left a comment

Choose a reason for hiding this comment

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

cr ACK 73f0a6c

@ryanofsky ryanofsky merged commit d38dbaa into bitcoin:master Jun 27, 2024
16 checks passed
@Sjors
Copy link
Member

Sjors commented Jul 2, 2024

Nice! Will try this out soon.

Update 2024-07-11: works like a charm and allowed me to drop some ugliness from systemd config.

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.

None yet

10 participants