diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 0d57a56297..2651cc9bc6 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include using util::SplitString; @@ -308,7 +309,7 @@ static bool InitRPCAuthentication() } assert(strRPCUserColonPass.empty()); // Only support initializing once - if (!GenerateAuthCookie(&strRPCUserColonPass, cookie_perms)) { + if (!GenerateAuthCookie(&strRPCUserColonPass, std::make_pair(cookie_perms, bool(cookie_perms_arg)))) { return false; } if (strRPCUserColonPass.empty()) { diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp index d1b0ed006b..a80ba9e08f 100644 --- a/src/rpc/request.cpp +++ b/src/rpc/request.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include /** @@ -97,7 +98,7 @@ static fs::path GetAuthCookieFile(bool temp=false) static std::optional g_generated_cookie; -bool GenerateAuthCookie(std::string* cookie_out, std::optional cookie_perms) +bool GenerateAuthCookie(std::string* cookie_out, const std::pair, bool>& cookie_perms) { const size_t COOKIE_SIZE = 32; unsigned char rand_pwd[COOKIE_SIZE]; @@ -118,9 +119,9 @@ bool GenerateAuthCookie(std::string* cookie_out, std::optional cookie return false; } - if (cookie_perms) { + if (cookie_perms.first) { std::error_code code; - fs::permissions(filepath_tmp, cookie_perms.value(), fs::perm_options::replace, code); + fs::permissions(filepath_tmp, cookie_perms.first.value(), fs::perm_options::replace, code); if (code) { LogWarning("Unable to set permissions on cookie authentication file %s", fs::PathToString(filepath_tmp)); return false; @@ -138,7 +139,9 @@ bool GenerateAuthCookie(std::string* cookie_out, std::optional cookie g_generated_cookie = cookie; LogInfo("Generated RPC authentication cookie %s\n", fs::PathToString(filepath)); - LogInfo("Permissions used for cookie: %s\n", PermsToSymbolicString(fs::status(filepath).permissions())); + LogInfo("Permissions used for cookie%s: %s\n", + (cookie_perms.first && cookie_perms.second) ? " (set by -rpccookieperms)" : "", + PermsToSymbolicString(fs::status(filepath).permissions())); if (cookie_out) *cookie_out = cookie; diff --git a/src/rpc/request.h b/src/rpc/request.h index 6c08e6ee37..8d80b7a44e 100644 --- a/src/rpc/request.h +++ b/src/rpc/request.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -24,7 +25,7 @@ UniValue JSONRPCReplyObj(UniValue result, UniValue error, std::optional cookie_perms=std::nullopt); +bool GenerateAuthCookie(std::string* cookie_out, const std::pair, bool>& cookie_perms); /** Read the RPC authentication cookie from disk */ bool GetAuthCookie(std::string *cookie_out); /** Delete RPC authentication cookie from disk */ diff --git a/src/util/fs_helpers.cpp b/src/util/fs_helpers.cpp index 82cf3a6ed2..02fe4910c2 100644 --- a/src/util/fs_helpers.cpp +++ b/src/util/fs_helpers.cpp @@ -325,21 +325,37 @@ std::string PermsToSymbolicString(fs::perms p) { std::string perm_str(9, '-'); - auto set_perm = [&](size_t pos, fs::perms required_perm, char letter) { + auto set_perm = [&](size_t pos, fs::perms required_perm, char letter, char else_letter = '\0') { if ((p & required_perm) != fs::perms::none) { perm_str[pos] = letter; + } else if (else_letter) { + perm_str[pos] = else_letter; } }; set_perm(0, fs::perms::owner_read, 'r'); set_perm(1, fs::perms::owner_write, 'w'); - set_perm(2, fs::perms::owner_exec, 'x'); + if ((p & fs::perms::owner_exec) != fs::perms::none) { + set_perm(2, fs::perms::set_uid, 's', 'x'); + } else { + set_perm(2, fs::perms::set_uid, 'S'); + } + set_perm(3, fs::perms::group_read, 'r'); set_perm(4, fs::perms::group_write, 'w'); - set_perm(5, fs::perms::group_exec, 'x'); + if ((p & fs::perms::group_exec) != fs::perms::none) { + set_perm(5, fs::perms::set_gid, 's', 'x'); + } else { + set_perm(5, fs::perms::set_gid, 'S'); + } + set_perm(6, fs::perms::others_read, 'r'); set_perm(7, fs::perms::others_write, 'w'); - set_perm(8, fs::perms::others_exec, 'x'); + if ((p & fs::perms::others_exec) != fs::perms::none) { + set_perm(8, fs::perms::sticky_bit, 't', 'x'); + } else { + set_perm(8, fs::perms::sticky_bit, 'T'); + } return perm_str; }