aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2017-08-28 09:40:08 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2017-08-28 09:40:15 +0200
commitc7229ac36e366ec4e23e3c131abf3bb3736b7e5d (patch)
treeaa1794d770ee294534ae3550c96c8e8b8c62f4ce
parent5b8af7b8791366906c81eeaf76275470849fb103 (diff)
parent82dd7195e1fb943f9cd45a48188f9678219c0206 (diff)
downloadbitcoin-c7229ac36e366ec4e23e3c131abf3bb3736b7e5d.tar.xz
Merge #11131: rpc: Write authcookie atomically
82dd719 rpc: Write authcookie atomically (Wladimir J. van der Laan) Pull request description: Use POSIX rename atomicity at the `bitcoind` side to create a working cookie atomically: - Write `.cookie.tmp`, close file - Rename `.cookie.tmp` to `.cookie` This avoids clients reading invalid/partial cookies as in #11129. As such, this is an alternative to that PR. Tree-SHA512: 47fcc1ed2ff3d8fed4b7441e4939f29cc99b57b7a035673c3b55a124a2e49c8a904637a6ff700dd13a184be8c0255707d74781f8e626314916418954e2467e03
-rw-r--r--src/rpc/protocol.cpp21
-rw-r--r--src/rpc/protocol.h2
2 files changed, 16 insertions, 7 deletions
diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp
index db0626b5e1..dc6bcec382 100644
--- a/src/rpc/protocol.cpp
+++ b/src/rpc/protocol.cpp
@@ -66,9 +66,14 @@ static const std::string COOKIEAUTH_USER = "__cookie__";
/** Default name for auth cookie file */
static const std::string COOKIEAUTH_FILE = ".cookie";
-fs::path GetAuthCookieFile()
+/** Get name of RPC authentication cookie file */
+static fs::path GetAuthCookieFile(bool temp=false)
{
- fs::path path(gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE));
+ std::string arg = gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE);
+ if (temp) {
+ arg += ".tmp";
+ }
+ fs::path path(arg);
if (!path.is_complete()) path = GetDataDir() / path;
return path;
}
@@ -84,14 +89,20 @@ bool GenerateAuthCookie(std::string *cookie_out)
* these are set to 077 in init.cpp unless overridden with -sysperms.
*/
std::ofstream file;
- fs::path filepath = GetAuthCookieFile();
- file.open(filepath.string().c_str());
+ fs::path filepath_tmp = GetAuthCookieFile(true);
+ file.open(filepath_tmp.string().c_str());
if (!file.is_open()) {
- LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string());
+ LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string());
return false;
}
file << cookie;
file.close();
+
+ fs::path filepath = GetAuthCookieFile(false);
+ if (!RenameOver(filepath_tmp, filepath)) {
+ LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp.string(), filepath.string());
+ return false;
+ }
LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
if (cookie_out)
diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h
index 4bd4702d62..5c9c64f67d 100644
--- a/src/rpc/protocol.h
+++ b/src/rpc/protocol.h
@@ -91,8 +91,6 @@ UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const Un
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
UniValue JSONRPCError(int code, const std::string& message);
-/** Get name of RPC authentication cookie file */
-fs::path GetAuthCookieFile();
/** Generate a new RPC authentication cookie and write it to disk */
bool GenerateAuthCookie(std::string *cookie_out);
/** Read the RPC authentication cookie from disk */