1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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>
19 * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
20 * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
21 * unspecified (HTTP errors and contents of 'error').
23 * 1.0 spec: http://json-rpc.org/wiki/specification
24 * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
27 UniValue
JSONRPCRequestObj(const std::string
& strMethod
, const UniValue
& params
, const UniValue
& id
)
29 UniValue
request(UniValue::VOBJ
);
30 request
.push_back(Pair("method", strMethod
));
31 request
.push_back(Pair("params", params
));
32 request
.push_back(Pair("id", id
));
36 UniValue
JSONRPCReplyObj(const UniValue
& result
, const UniValue
& error
, const UniValue
& id
)
38 UniValue
reply(UniValue::VOBJ
);
40 reply
.push_back(Pair("result", NullUniValue
));
42 reply
.push_back(Pair("result", result
));
43 reply
.push_back(Pair("error", error
));
44 reply
.push_back(Pair("id", id
));
48 std::string
JSONRPCReply(const UniValue
& result
, const UniValue
& error
, const UniValue
& id
)
50 UniValue reply
= JSONRPCReplyObj(result
, error
, id
);
51 return reply
.write() + "\n";
54 UniValue
JSONRPCError(int code
, const std::string
& message
)
56 UniValue
error(UniValue::VOBJ
);
57 error
.push_back(Pair("code", code
));
58 error
.push_back(Pair("message", message
));
62 /** Username used when cookie authentication is in use (arbitrary, only for
63 * recognizability in debugging/logging purposes)
65 static const std::string COOKIEAUTH_USER
= "__cookie__";
66 /** Default name for auth cookie file */
67 static const std::string COOKIEAUTH_FILE
= ".cookie";
69 /** Get name of RPC authentication cookie file */
70 static fs::path
GetAuthCookieFile(bool temp
=false)
72 std::string arg
= gArgs
.GetArg("-rpccookiefile", COOKIEAUTH_FILE
);
77 if (!path
.is_complete()) path
= GetDataDir() / path
;
81 bool GenerateAuthCookie(std::string
*cookie_out
)
83 const size_t COOKIE_SIZE
= 32;
84 unsigned char rand_pwd
[COOKIE_SIZE
];
85 GetRandBytes(rand_pwd
, COOKIE_SIZE
);
86 std::string cookie
= COOKIEAUTH_USER
+ ":" + HexStr(rand_pwd
, rand_pwd
+COOKIE_SIZE
);
88 /** the umask determines what permissions are used to create this file -
89 * these are set to 077 in init.cpp unless overridden with -sysperms.
92 fs::path filepath_tmp
= GetAuthCookieFile(true);
93 file
.open(filepath_tmp
.string().c_str());
94 if (!file
.is_open()) {
95 LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp
.string());
101 fs::path filepath
= GetAuthCookieFile(false);
102 if (!RenameOver(filepath_tmp
, filepath
)) {
103 LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp
.string(), filepath
.string());
106 LogPrintf("Generated RPC authentication cookie %s\n", filepath
.string());
109 *cookie_out
= cookie
;
113 bool GetAuthCookie(std::string
*cookie_out
)
117 fs::path filepath
= GetAuthCookieFile();
118 file
.open(filepath
.string().c_str());
121 std::getline(file
, cookie
);
125 *cookie_out
= cookie
;
129 void DeleteAuthCookie()
132 fs::remove(GetAuthCookieFile());
133 } catch (const fs::filesystem_error
& e
) {
134 LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__
, e
.what());
138 std::vector
<UniValue
> JSONRPCProcessBatchReply(const UniValue
&in
, size_t num
)
141 throw std::runtime_error("Batch must be an array");
143 std::vector
<UniValue
> batch(num
);
144 for (size_t i
=0; i
<in
.size(); ++i
) {
145 const UniValue
&rec
= in
[i
];
146 if (!rec
.isObject()) {
147 throw std::runtime_error("Batch member must be object");
149 size_t id
= rec
["id"].get_int();
151 throw std::runtime_error("Batch member id larger than size");