Bitcoin Core 22.99.0
P2P Digital Currency
request.cpp
Go to the documentation of this file.
1// Copyright (c) 2010 Satoshi Nakamoto
2// Copyright (c) 2009-2020 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include <rpc/request.h>
7
8#include <fs.h>
9
10#include <random.h>
11#include <rpc/protocol.h>
12#include <util/system.h>
13#include <util/strencodings.h>
14
24UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id)
25{
26 UniValue request(UniValue::VOBJ);
27 request.pushKV("method", strMethod);
28 request.pushKV("params", params);
29 request.pushKV("id", id);
30 return request;
31}
32
33UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
34{
36 if (!error.isNull())
37 reply.pushKV("result", NullUniValue);
38 else
39 reply.pushKV("result", result);
40 reply.pushKV("error", error);
41 reply.pushKV("id", id);
42 return reply;
43}
44
45std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
46{
47 UniValue reply = JSONRPCReplyObj(result, error, id);
48 return reply.write() + "\n";
49}
50
51UniValue JSONRPCError(int code, const std::string& message)
52{
54 error.pushKV("code", code);
55 error.pushKV("message", message);
56 return error;
57}
58
62static const std::string COOKIEAUTH_USER = "__cookie__";
64static const std::string COOKIEAUTH_FILE = ".cookie";
65
67static fs::path GetAuthCookieFile(bool temp=false)
68{
69 std::string arg = gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE);
70 if (temp) {
71 arg += ".tmp";
72 }
74}
75
76bool GenerateAuthCookie(std::string *cookie_out)
77{
78 const size_t COOKIE_SIZE = 32;
79 unsigned char rand_pwd[COOKIE_SIZE];
80 GetRandBytes(rand_pwd, COOKIE_SIZE);
81 std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd);
82
87 fs::path filepath_tmp = GetAuthCookieFile(true);
88 file.open(filepath_tmp);
89 if (!file.is_open()) {
90 LogPrintf("Unable to open cookie authentication file %s for writing\n", fs::PathToString(filepath_tmp));
91 return false;
92 }
93 file << cookie;
94 file.close();
95
96 fs::path filepath = GetAuthCookieFile(false);
97 if (!RenameOver(filepath_tmp, filepath)) {
98 LogPrintf("Unable to rename cookie authentication file %s to %s\n", fs::PathToString(filepath_tmp), fs::PathToString(filepath));
99 return false;
100 }
101 LogPrintf("Generated RPC authentication cookie %s\n", fs::PathToString(filepath));
102
103 if (cookie_out)
104 *cookie_out = cookie;
105 return true;
106}
107
108bool GetAuthCookie(std::string *cookie_out)
109{
111 std::string cookie;
112 fs::path filepath = GetAuthCookieFile();
113 file.open(filepath);
114 if (!file.is_open())
115 return false;
116 std::getline(file, cookie);
117 file.close();
118
119 if (cookie_out)
120 *cookie_out = cookie;
121 return true;
122}
123
125{
126 try {
127 fs::remove(GetAuthCookieFile());
128 } catch (const fs::filesystem_error& e) {
129 LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, fsbridge::get_filesystem_error_message(e));
130 }
131}
132
133std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue& in)
134{
135 if (!in.isArray()) {
136 throw std::runtime_error("Batch must be an array");
137 }
138 const size_t num {in.size()};
139 std::vector<UniValue> batch(num);
140 for (const UniValue& rec : in.getValues()) {
141 if (!rec.isObject()) {
142 throw std::runtime_error("Batch member must be an object");
143 }
144 size_t id = rec["id"].get_int();
145 if (id >= num) {
146 throw std::runtime_error("Batch member id is larger than batch size");
147 }
148 batch[id] = rec;
149 }
150 return batch;
151}
152
153void JSONRPCRequest::parse(const UniValue& valRequest)
154{
155 // Parse request
156 if (!valRequest.isObject())
157 throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
158 const UniValue& request = valRequest.get_obj();
159
160 // Parse id now so errors from here on will have the id
161 id = find_value(request, "id");
162
163 // Parse method
164 UniValue valMethod = find_value(request, "method");
165 if (valMethod.isNull())
166 throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
167 if (!valMethod.isStr())
168 throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
169 strMethod = valMethod.get_str();
170 if (fLogIPs)
171 LogPrint(BCLog::RPC, "ThreadRPCServer method=%s user=%s peeraddr=%s\n", SanitizeString(strMethod),
172 this->authUser, this->peerAddr);
173 else
174 LogPrint(BCLog::RPC, "ThreadRPCServer method=%s user=%s\n", SanitizeString(strMethod), this->authUser);
175
176 // Parse params
177 UniValue valParams = find_value(request, "params");
178 if (valParams.isArray() || valParams.isObject())
179 params = valParams;
180 else if (valParams.isNull())
182 else
183 throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array or object");
184}
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:590
UniValue params
Definition: request.h:33
std::string strMethod
Definition: request.h:32
std::string peerAddr
Definition: request.h:37
void parse(const UniValue &valRequest)
Definition: request.cpp:153
std::string authUser
Definition: request.h:36
const std::string & get_str() const
bool isArray() const
Definition: univalue.h:81
@ VOBJ
Definition: univalue.h:19
@ VARR
Definition: univalue.h:19
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool isNull() const
Definition: univalue.h:75
const UniValue & get_obj() const
size_t size() const
Definition: univalue.h:66
const std::vector< UniValue > & getValues() const
bool isStr() const
Definition: univalue.h:79
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
bool isObject() const
Definition: univalue.h:82
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
Definition: fs.h:34
static NodeId id
bool fLogIPs
Definition: logging.cpp:38
#define LogPrint(category,...)
Definition: logging.h:191
#define LogPrintf(...)
Definition: logging.h:187
@ RPC
Definition: logging.h:45
static std::string PathToString(const path &path)
Convert path object to byte string.
Definition: fs.h:120
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:133
fs::ofstream ofstream
Definition: fs.h:225
std::string get_filesystem_error_message(const fs::filesystem_error &e)
Definition: fs.cpp:138
fs::ifstream ifstream
Definition: fs.h:224
void GetRandBytes(unsigned char *buf, int num) noexcept
Overall design of the RNG and entropy sources.
Definition: random.cpp:584
static fs::path GetAuthCookieFile(bool temp=false)
Get name of RPC authentication cookie file.
Definition: request.cpp:67
std::vector< UniValue > JSONRPCProcessBatchReply(const UniValue &in)
Parse JSON-RPC batch reply into a vector.
Definition: request.cpp:133
bool GetAuthCookie(std::string *cookie_out)
Read the RPC authentication cookie from disk.
Definition: request.cpp:108
std::string JSONRPCReply(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:45
UniValue JSONRPCRequestObj(const std::string &strMethod, const UniValue &params, const UniValue &id)
JSON-RPC protocol.
Definition: request.cpp:24
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:51
void DeleteAuthCookie()
Delete RPC authentication cookie from disk.
Definition: request.cpp:124
static const std::string COOKIEAUTH_FILE
Default name for auth cookie file.
Definition: request.cpp:64
bool GenerateAuthCookie(std::string *cookie_out)
Generate a new RPC authentication cookie and write it to disk.
Definition: request.cpp:76
UniValue JSONRPCReplyObj(const UniValue &result, const UniValue &error, const UniValue &id)
Definition: request.cpp:33
static const std::string COOKIEAUTH_USER
Username used when cookie authentication is in use (arbitrary, only for recognizability in debugging/...
Definition: request.cpp:62
@ RPC_INVALID_REQUEST
Standard JSON-RPC 2.0 errors.
Definition: protocol.h:28
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
const UniValue NullUniValue
Definition: univalue.cpp:13
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
Definition: system.cpp:1368
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:1065
ArgsManager gArgs
Definition: system.cpp:85