1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2017 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.
6 #include <rpc/protocol.h>
9 #include <tinyformat.h>
11 #include <utilstrencodings.h>
18 * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
19 * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
20 * unspecified (HTTP errors and contents of 'error').
22 * 1.0 spec: http://json-rpc.org/wiki/specification
23 * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
26 UniValue
JSONRPCRequestObj(const std::string
& strMethod
, const UniValue
& params
, const UniValue
& id
)
28 UniValue
request(UniValue::VOBJ
);
29 request
.push_back(Pair("method", strMethod
));
30 request
.push_back(Pair("params", params
));
31 request
.push_back(Pair("id", id
));
35 UniValue
JSONRPCReplyObj(const UniValue
& result
, const UniValue
& error
, const UniValue
& id
)
37 UniValue
reply(UniValue::VOBJ
);
39 reply
.push_back(Pair("result", NullUniValue
));
41 reply
.push_back(Pair("result", result
));
42 reply
.push_back(Pair("error", error
));
43 reply
.push_back(Pair("id", id
));
47 std::string
JSONRPCReply(const UniValue
& result
, const UniValue
& error
, const UniValue
& id
)
49 UniValue reply
= JSONRPCReplyObj(result
, error
, id
);
50 return reply
.write() + "\n";
53 UniValue
JSONRPCError(int code
, const std::string
& message
)
55 UniValue
error(UniValue::VOBJ
);
56 error
.push_back(Pair("code", code
));
57 error
.push_back(Pair("message", message
));
61 /** Username used when cookie authentication is in use (arbitrary, only for
62 * recognizability in debugging/logging purposes)
64 static const std::string COOKIEAUTH_USER
= "__cookie__";
65 /** Default name for auth cookie file */
66 static const std::string COOKIEAUTH_FILE
= ".cookie";
68 /** Get name of RPC authentication cookie file */
69 static fs::path
GetAuthCookieFile(bool temp
=false)
71 std::string arg
= gArgs
.GetArg("-rpccookiefile", COOKIEAUTH_FILE
);
76 if (!path
.is_complete()) path
= GetDataDir() / path
;
80 bool GenerateAuthCookie(std::string
*cookie_out
)
82 const size_t COOKIE_SIZE
= 32;
83 unsigned char rand_pwd
[COOKIE_SIZE
];
84 GetRandBytes(rand_pwd
, COOKIE_SIZE
);
85 std::string cookie
= COOKIEAUTH_USER
+ ":" + HexStr(rand_pwd
, rand_pwd
+COOKIE_SIZE
);
87 /** the umask determines what permissions are used to create this file -
88 * these are set to 077 in init.cpp unless overridden with -sysperms.
91 fs::path filepath_tmp
= GetAuthCookieFile(true);
92 file
.open(filepath_tmp
.string().c_str());
93 if (!file
.is_open()) {
94 LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp
.string());
100 fs::path filepath
= GetAuthCookieFile(false);
101 if (!RenameOver(filepath_tmp
, filepath
)) {
102 LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp
.string(), filepath
.string());
105 LogPrintf("Generated RPC authentication cookie %s\n", filepath
.string());
108 *cookie_out
= cookie
;
112 bool GetAuthCookie(std::string
*cookie_out
)
116 fs::path filepath
= GetAuthCookieFile();
117 file
.open(filepath
.string().c_str());
120 std::getline(file
, cookie
);
124 *cookie_out
= cookie
;
128 void DeleteAuthCookie()
131 fs::remove(GetAuthCookieFile());
132 } catch (const fs::filesystem_error
& e
) {
133 LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__
, e
.what());
137 std::vector
<UniValue
> JSONRPCProcessBatchReply(const UniValue
&in
, size_t num
)
140 throw std::runtime_error("Batch must be an array");
142 std::vector
<UniValue
> batch(num
);
143 for (size_t i
=0; i
<in
.size(); ++i
) {
144 const UniValue
&rec
= in
[i
];
145 if (!rec
.isObject()) {
146 throw std::runtime_error("Batch member must be object");
148 size_t id
= rec
["id"].get_int();
150 throw std::runtime_error("Batch member id larger than size");