|
6 | 6 | #include "rpcprotocol.h" |
7 | 7 |
|
8 | 8 | #include "clientversion.h" |
| 9 | +#include "random.h" |
9 | 10 | #include "tinyformat.h" |
10 | 11 | #include "util.h" |
11 | 12 | #include "utilstrencodings.h" |
12 | 13 | #include "utiltime.h" |
13 | 14 | #include "version.h" |
14 | 15 |
|
15 | 16 | #include <stdint.h> |
| 17 | +#include <fstream> |
16 | 18 |
|
17 | 19 | #include <boost/algorithm/string.hpp> |
18 | 20 | #include <boost/asio.hpp> |
@@ -287,3 +289,68 @@ UniValue JSONRPCError(int code, const string& message) |
287 | 289 | error.push_back(Pair("message", message)); |
288 | 290 | return error; |
289 | 291 | } |
| 292 | + |
| 293 | +/** Username used when cookie authentication is in use (arbitrary, only for |
| 294 | + * recognizability in debugging/logging purposes) |
| 295 | + */ |
| 296 | +static const std::string COOKIEAUTH_USER = "__cookie__"; |
| 297 | +/** Default name for auth cookie file */ |
| 298 | +static const std::string COOKIEAUTH_FILE = ".cookie"; |
| 299 | + |
| 300 | +boost::filesystem::path GetAuthCookieFile() |
| 301 | +{ |
| 302 | + boost::filesystem::path path(GetArg("-rpccookiefile", COOKIEAUTH_FILE)); |
| 303 | + if (!path.is_complete()) path = GetDataDir() / path; |
| 304 | + return path; |
| 305 | +} |
| 306 | + |
| 307 | +bool GenerateAuthCookie(std::string *cookie_out) |
| 308 | +{ |
| 309 | + unsigned char rand_pwd[32]; |
| 310 | + GetRandBytes(rand_pwd, 32); |
| 311 | + std::string cookie = COOKIEAUTH_USER + ":" + EncodeBase64(&rand_pwd[0],32); |
| 312 | + |
| 313 | + /** the umask determines what permissions are used to create this file - |
| 314 | + * these are set to 077 in init.cpp unless overridden with -sysperms. |
| 315 | + */ |
| 316 | + std::ofstream file; |
| 317 | + boost::filesystem::path filepath = GetAuthCookieFile(); |
| 318 | + file.open(filepath.string().c_str()); |
| 319 | + if (!file.is_open()) { |
| 320 | + LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath.string()); |
| 321 | + return false; |
| 322 | + } |
| 323 | + file << cookie; |
| 324 | + file.close(); |
| 325 | + LogPrintf("Generated RPC authentication cookie %s\n", filepath.string()); |
| 326 | + |
| 327 | + if (cookie_out) |
| 328 | + *cookie_out = cookie; |
| 329 | + return true; |
| 330 | +} |
| 331 | + |
| 332 | +bool GetAuthCookie(std::string *cookie_out) |
| 333 | +{ |
| 334 | + std::ifstream file; |
| 335 | + std::string cookie; |
| 336 | + boost::filesystem::path filepath = GetAuthCookieFile(); |
| 337 | + file.open(filepath.string().c_str()); |
| 338 | + if (!file.is_open()) |
| 339 | + return false; |
| 340 | + std::getline(file, cookie); |
| 341 | + file.close(); |
| 342 | + |
| 343 | + if (cookie_out) |
| 344 | + *cookie_out = cookie; |
| 345 | + return true; |
| 346 | +} |
| 347 | + |
| 348 | +void DeleteAuthCookie() |
| 349 | +{ |
| 350 | + try { |
| 351 | + boost::filesystem::remove(GetAuthCookieFile()); |
| 352 | + } catch (const boost::filesystem::filesystem_error& e) { |
| 353 | + LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what()); |
| 354 | + } |
| 355 | +} |
| 356 | + |
0 commit comments