Skip to content

Conversation

aureleoules
Copy link
Contributor

@aureleoules aureleoules commented Sep 14, 2022

Adds a bitcoind launch option -rpccookieperms to configure the file permissions of the cookie.
Can be used like ./src/bitcoind -rpccookieperms=0660

Closes #25270.

@fanquake
Copy link
Member

https://github.com/bitcoin/bitcoin/pull/26088/checks?check_run_id=8346907823:

The locale dependent function strtol(...) appears to be used:
src/httprpc.cpp:            const auto perms{strtol(cookie_perms_arg->c_str(), &cookie_perms_end, 8)};

Unnecessary locale depedence can cause bugs that are very tricky to isolate and fix. Please avoid using locale dependent functions if possible.

@aureleoules aureleoules force-pushed the 2022-09-rpccookie-perms branch 2 times, most recently from 54f4839 to 8d7a71b Compare September 14, 2022 09:39
@aureleoules
Copy link
Contributor Author

Fixed lint error.

@aureleoules aureleoules force-pushed the 2022-09-rpccookie-perms branch from 8d7a71b to aa5afed Compare September 14, 2022 09:46
@aureleoules aureleoules force-pushed the 2022-09-rpccookie-perms branch from aa5afed to 857d46e Compare September 14, 2022 17:28
Copy link
Contributor

@kristapsk kristapsk left a comment

Choose a reason for hiding this comment

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

ACK 857d46e

@ghost
Copy link

ghost commented Sep 15, 2022

This will work only for Linux. Added a few lines in src/rpc/request.cpp from an example on https://en.cppreference.com/w/cpp/filesystem/permissions to test and print permissions in logs:

diff
+void perms(fs::perms p)
+{
+   std::cout << ((p & fs::perms::owner_read) != fs::perms::none ? "r" : "-")
+             << ((p & fs::perms::owner_write) != fs::perms::none ? "w" : "-")
+              << ((p & fs::perms::owner_exec) != fs::perms::none ? "x" : "-")
+              << ((p & fs::perms::group_read) != fs::perms::none ? "r" : "-")
+              << ((p & fs::perms::group_write) != fs::perms::none ? "w" : "-")
+              << ((p & fs::perms::group_exec) != fs::perms::none ? "x" : "-")
+              << ((p & fs::perms::others_read) != fs::perms::none ? "r" : "-")
+              << ((p & fs::perms::others_write) != fs::perms::none ? "w" : "-")
+              << ((p & fs::perms::others_exec) != fs::perms::none ? "x" : "-")
+              << '\n';
+}

bool GenerateAuthCookie(std::string* cookie_out, std::optional<fs::perms> cookie_perms)
{
  const size_t COOKIE_SIZE = 32;
  unsigned char rand_pwd[COOKIE_SIZE];
  GetRandBytes(rand_pwd);
  std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd);

  /** the umask determines what permissions are used to create this file -
   * these are set to 077 in init.cpp unless overridden with -sysperms.
   */
  std::ofstream file;
  fs::path filepath_tmp = GetAuthCookieFile(true);
  file.open(filepath_tmp);
  if (!file.is_open()) {
      LogPrintf("Unable to open cookie authentication file %s for writing\n", fs::PathToString(filepath_tmp));
      return false;
  }
  file << cookie;
  file.close();

  if (cookie_perms) {
      std::error_code code;
      std::filesystem::permissions(filepath_tmp, *cookie_perms, std::filesystem::perm_options::replace, code);
      if (code) {
          LogPrintf("Unable to set permissions on cookie authentication file %s\n", fs::PathToString(filepath_tmp));
          return false;
      }
  }

  fs::path filepath = GetAuthCookieFile(false);
  if (!RenameOver(filepath_tmp, filepath)) {
      LogPrintf("Unable to rename cookie authentication file %s to %s\n", fs::PathToString(filepath_tmp), fs::PathToString(filepath));
      return false;
  }
  LogPrintf("Generated RPC authentication cookie %s\n", fs::PathToString(filepath));
+ LogPrintf("Permissions used for cookie: ");
+ perms(fs::status(filepath).permissions());

  if (cookie_out)
      *cookie_out = cookie;
  return true;
}

Windows:

.\bitcoind.exe

2022-09-15T09:57:30Z Using random cookie authentication.
2022-09-15T09:57:30Z Generated RPC authentication cookie C:\Users\test\AppData\Roaming\Bitcoin\signet\.cookie
2022-09-15T09:57:30Z Permissions used for cookie: rw-rw-rw-

.\bitcoind.exe -rpccookieperms=0660

2022-09-15T09:51:36Z Using random cookie authentication.
2022-09-15T09:51:36Z Generated RPC authentication cookie C:\Users\test\AppData\Roaming\Bitcoin\signet\.cookie
2022-09-15T09:51:36Z Permissions used for cookie: rw-rw-rw-

Fedora:

bitcoind

2022-09-15T11:34:59Z Using random cookie authentication.
2022-09-15T11:34:59Z Generated RPC authentication cookie /home/test/.bitcoin/regtest/.cookie
2022-09-15T11:34:59Z Permissions used for cookie: rw-------

bitcoind -rpccookieperms=0660

2022-09-15T11:39:37Z Using random cookie authentication.
2022-09-15T11:39:37Z Generated RPC authentication cookie /home/test/.bitcoin/regtest/.cookie
2022-09-15T11:39:37Z Permissions used for cookie: rw-rw----

Adds a bitcoind launch option `-rpccookieperms` to configure
the file permissions of the cookie.
@aureleoules aureleoules force-pushed the 2022-09-rpccookie-perms branch from 857d46e to cc0d0ae Compare September 16, 2022 19:10
@aureleoules
Copy link
Contributor Author

Added the log message with a slightly modified version. Thanks @1440000bytes.

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

ACK cc0d0ae

I don't have the time time to test it furtther

@DrahtBot
Copy link
Contributor

DrahtBot commented Sep 23, 2022

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

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK 1440000bytes
Stale ACK kristapsk

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

Conflicts

No conflicts as of last run.

@dongcarl
Copy link
Contributor

I'm wondering: would it be perhaps simpler to just state in the documentation that you should run bitcoind with a umask of 0002 and specify -sysperms if you want group access to the cookie?

A consideration here is that now all bitcoind created files will be group accessible including wallet files, but given that the group has access to the cookie, if they have the wallet password they can still dumpwallet, so the UNIX permissions don't matter as much (or is just a defense-in-depth thing). It seems that #17127 also solves this as well.

In any case, this is something that I run into time and again when deploying Bitcoin Core alongside other services, so I'd love to see some documentation on it.

@fanquake
Copy link
Member

fanquake commented Feb 6, 2023

@aureleoules did you want to reponds to Carls thoughts here?

It seems that #17127 also solves this as well.

It's probably likey that 17127 will be merged shortly.

@aureleoules
Copy link
Contributor Author

I don't have a preference as I don't have much experience using this feature.
Happy to close this PR if #17127 gets merged.

@fanquake
Copy link
Member

fanquake commented Feb 7, 2023

Happy to close this PR if #17127 gets merged.

17127 has been merged. Closing this.

@willcl-ark
Copy link
Member

@aureleoules @fanquake

I think this could be re-opened to solve #25270 if @aureleoules is happy to pick it up again, otherwise I'd be happy to?

Whilst #17127 has given us more sane and secure defaults, permitting group members to access the cookie without resorting to -startupnotify wortkarounds or similar seems reasonable to me.

One the one hand any processes with access to the cookie could just as well be running as the same user as bitcoind on the host, as the cookie essentially gives them full access to funds. And if users took that approach this change wouldn't be necessary. But I also understand people's desire for compartmentalisation and running different processes as different users, who share a group.

If we don't want to include this feature (but I think we should) then we should opt to close #25270 also.

@aureleoules
Copy link
Contributor Author

I don't have much time to work on Core so feel free to pick this up @willcl-ark.

auto cookie_perms_arg{gArgs.GetArg("-rpccookieperms")};
if (cookie_perms_arg) {
auto perms{StringToOctal(*cookie_perms_arg)};
if (!perms) {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe check that cookie_perms_arg isn't a 1/parameterless.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the reminder on this luke, as I said I'd take it up previously. I took these changes in opening #28167

@@ -98,12 +111,22 @@ bool GenerateAuthCookie(std::string *cookie_out)
file << cookie;
Copy link
Member

Choose a reason for hiding this comment

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

Should probably set permissions before writing to the file (but after opening it, so we already have write access), just in case they are more restrictive?

#include <string>

#include <fs.h>
Copy link
Member

Choose a reason for hiding this comment

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

Rebase, <util/fs.h>

fs::path filepath = GetAuthCookieFile(false);
if (!RenameOver(filepath_tmp, filepath)) {
LogPrintf("Unable to rename cookie authentication file %s to %s\n", fs::PathToString(filepath_tmp), fs::PathToString(filepath));
return false;
}
LogPrintf("Generated RPC authentication cookie %s\n", fs::PathToString(filepath));
LogPrintf("Permissions used for cookie: %s\n", perms_to_str(fs::status(filepath).permissions()));
Copy link
Member

Choose a reason for hiding this comment

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

    LogPrintf("Permissions used for cookie%s: %s\n",
              cookie_perms ? " (set by -rpccookieperms)" : "",
              perms_to_str(fs::status(filepath).permissions()));

luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Aug 16, 2023
Adds a bitcoind launch option `-rpccookieperms` to configure
the file permissions of the cookie.

Github-Pull: bitcoin#26088
Rebased-From: cc0d0ae
ryanofsky added a commit that referenced this pull request Jun 27, 2024
73f0a6c doc: detail -rpccookieperms option (willcl-ark)
d2afa26 test: add rpccookieperms test (willcl-ark)
f467aed init: add option for rpccookie permissions (willcl-ark)
7df03f1 util: add perm string helper functions (willcl-ark)

Pull request description:

  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.

ACKs for top commit:
  achow101:
    ACK 73f0a6c
  ryanofsky:
    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.
  tdb3:
    cr ACK 73f0a6c

Tree-SHA512: e800d59a44aca10e1c58ca69bf3fdde9f6ccf5eab4b7b962645af6d6bc0cfa3a357701e409c8c60d8d7744fcd33a91e77ada11790aa88cd7811ef60fab86ab11
@bitcoin bitcoin locked and limited conversation to collaborators Jul 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow groups of accounts to access the RPC cookie file
9 participants