diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-08-25 12:39:30 +0200 |
---|---|---|
committer | MarcoFalke <falke.marco@gmail.com> | 2017-10-03 18:34:30 +0200 |
commit | b278a43646c8fb331a1b830b09a60ec2544dd6b6 (patch) | |
tree | 829882527cd8fb64d62bc9ec2e745aaf1d9223ad /src/rpc/protocol.cpp | |
parent | 50bd3f626d7ce35d52543b88a2e512074f9df134 (diff) | |
download | bitcoin-b278a43646c8fb331a1b830b09a60ec2544dd6b6.tar.xz |
rpc: Write authcookie atomically
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.
Github-Pull: #11131
Rebased-From: 82dd7195e1fb943f9cd45a48188f9678219c0206
Diffstat (limited to 'src/rpc/protocol.cpp')
-rw-r--r-- | src/rpc/protocol.cpp | 21 |
1 files changed, 16 insertions, 5 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) |