Line data Source code
1 : // Copyright (c) 2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2014 The Bitcoin developers 3 : // Copyright (c) 2014-2015 The Dash developers 4 : // Copyright (c) 2015-2021 The PIVX Core developers 5 : // Distributed under the MIT software license, see the accompanying 6 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 7 : 8 : #include "rpc/protocol.h" 9 : 10 : #include "random.h" 11 : #include "tinyformat.h" 12 : #include "util/system.h" 13 : #include "utilstrencodings.h" 14 : #include "utiltime.h" 15 : 16 : /** 17 : * JSON-RPC protocol. PIVX speaks version 1.0 for maximum compatibility, 18 : * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were 19 : * unspecified (HTTP errors and contents of 'error'). 20 : * 21 : * 1.0 spec: http://json-rpc.org/wiki/specification 22 : * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html 23 : * http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx 24 : */ 25 : 26 3 : UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id) 27 : { 28 3 : UniValue request(UniValue::VOBJ); 29 3 : request.pushKV("method", strMethod); 30 3 : request.pushKV("params", params); 31 3 : request.pushKV("id", id); 32 3 : return request; 33 : } 34 : 35 298152 : UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id) 36 : { 37 298152 : UniValue reply(UniValue::VOBJ); 38 298152 : if (!error.isNull()) 39 576 : reply.pushKV("result", NullUniValue); 40 : else 41 595728 : reply.pushKV("result", result); 42 298152 : reply.pushKV("error", error); 43 298152 : reply.pushKV("id", id); 44 298152 : return reply; 45 : } 46 : 47 298150 : std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id) 48 : { 49 298150 : UniValue reply = JSONRPCReplyObj(result, error, id); 50 596300 : return reply.write() + "\n"; 51 : } 52 : 53 336 : UniValue JSONRPCError(int code, const std::string& message) 54 : { 55 336 : UniValue error(UniValue::VOBJ); 56 336 : error.pushKV("code", code); 57 336 : error.pushKV("message", message); 58 336 : return error; 59 : } 60 : 61 : /** Username used when cookie authentication is in use (arbitrary, only for 62 : * recognizability in debugging/logging purposes) 63 : */ 64 : static const std::string COOKIEAUTH_USER = "__cookie__"; 65 : /** Default name for auth cookie file */ 66 : static const std::string COOKIEAUTH_FILE = ".cookie"; 67 : 68 755 : fs::path GetAuthCookieFile() 69 : { 70 1510 : fs::path path(gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE)); 71 1510 : return AbsPathForConfigVal(path); 72 : } 73 : 74 374 : bool GenerateAuthCookie(std::string *cookie_out) 75 : { 76 374 : const size_t COOKIE_SIZE = 32; 77 374 : unsigned char rand_pwd[COOKIE_SIZE]; 78 374 : GetRandBytes(rand_pwd, COOKIE_SIZE); 79 1122 : std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd); 80 : 81 : /** the umask determines what permissions are used to create this file - 82 : * these are set to 077 in init.cpp unless overridden with -sysperms. 83 : */ 84 748 : fsbridge::ofstream file; 85 748 : fs::path filepath_tmp = GetAuthCookieFile(); 86 374 : file.open(filepath_tmp); 87 374 : if (!file.is_open()) { 88 0 : LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string()); 89 : return false; 90 : } 91 374 : file << cookie; 92 374 : file.close(); 93 374 : LogPrintf("Generated RPC authentication cookie %s\n", filepath_tmp.string()); 94 : 95 374 : if (cookie_out) 96 374 : *cookie_out = cookie; 97 : return true; 98 : } 99 : 100 3 : bool GetAuthCookie(std::string *cookie_out) 101 : { 102 3 : fsbridge::ifstream file; 103 6 : std::string cookie; 104 6 : fs::path filepath = GetAuthCookieFile(); 105 3 : file.open(filepath); 106 3 : if (!file.is_open()) 107 : return false; 108 3 : std::getline(file, cookie); 109 3 : file.close(); 110 : 111 3 : if (cookie_out) 112 3 : *cookie_out = cookie; 113 : return true; 114 : } 115 : 116 378 : void DeleteAuthCookie() 117 : { 118 378 : try { 119 1134 : fs::remove(GetAuthCookieFile()); 120 0 : } catch (const fs::filesystem_error& e) { 121 0 : LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); 122 : } 123 378 : }